I. Background
Under the microservices architecture, our systems are split into multiple, single-duty microservices based on business.
Each service has its own set of APIs to provide to other service calls, so how to ensure security.
It is not that you want to invoke the call, we must have the authentication mechanism, is the request from our internal service, we can call our interface.
Note that we are talking about the security authentication between microservices, not unified in the API certification, the demand is not the same, API Gateway Unified Authentication is and business-linked, our side is to prevent the interface is called by others. two. Programme OAUTH2
Spring Cloud can use OAUTH2 to implement unified authentication authorization for multiple microservices
Get Access_token by centralizing authentication and authorization to the OAUTH2 service
This token is trusted by other micro services, in the subsequent access to the Access_token brought in the past, so as to achieve a unified micro-service certification authority. JWT
JWT is a safety standard. The basic idea is that the user provides the user name and password to the authentication server, the server verifies the legality of the user's submission of information; If the validation succeeds, it generates and returns a token that the user can use to access the protected resources on the server.
Feel that these 2 kinds of seems not much difference, actually there is a difference: OAUTH2 is an authorization framework, JWT is a kind of authentication protocol
Regardless of the method used, remember to use HTTPS to ensure data security. three. What kind of
I personally recommend JWT, lightweight, simple, suitable for distributed stateless applications
With OAUTH2, the trouble point, the various roles, authentication type, client and so on a lot of concepts four. How to use
First, create a generic authentication service that provides authentication and returns a token after successful authentication
@RestController @RequestMapping (value= "/oauth") public class Authcontroller {@Autowired private authservice auth
Service; @PostMapping ("/token") public responsedata auth (@RequestBody authquery query) throws Exception {if (Stringuti Ls.isblank (Query.getaccesskey ()) | | Stringutils.isblank (Query.getsecretkey ())) {return Responsedata.failbyparam ("AccessKey and Secretkey NOT NULL
");
User user = Authservice.auth (query);
if (user = = null) {return Responsedata.failbyparam ("Authentication failed");
} jwtutils JWT = Jwtutils.getinstance ();
Return Responsedata.ok (Jwt.gettoken (User.getid (). toString ())); } @GetMapping ("/token") public responsedata OAuth (authquery query) throws Exception {if (STRINGUTILS.ISB Lank (Query.getaccesskey ()) | | Stringutils.isblank (Query.getsecretkey ())) {return Responsedata.failbyparam ("AccessKey and Secretkey NOT NULL
"); } User User = AUthservice.auth (query);
if (user = = null) {return Responsedata.failbyparam ("Authentication failed");
} jwtutils JWT = Jwtutils.getinstance ();
Return Responsedata.ok (Jwt.gettoken (User.getid (). toString ())); }
}
JWT can join the dependency, and then write a tool class, it is recommended to write in the global package, all services are used, the specific code please refer to: jwtutils
GitHub Address: HTTPS://GITHUB.COM/JWTK/JJWT
JWT provides a lot of encryption algorithm, I use RSA, now is a set of public key and private key, this practice is not good at present, because in case the secret key leaks, it is not safe, so the latter will use the configuration center to dynamically manage the secret key.
The main logic in a class is to generate tokens, and then provide a way to check whether tokens are legitimate, whether they expire, and so on.
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactid>jjwt</ artifactid>
<version>0.7.0</version>
</dependency>
The Unified authentication Service has, we only need to register the attestation service to the registration center to the other service consumption.
So how do we use just the certification service to do certification, the simplest way is to use filter to deal with
For example, I now have a service fangjia-fsh-house-service, before anyone can call me to provide the interface, and now I want to join the verification, only the verification pass can let it call my interface
Then add a filter in the Fangjia-fsh-house-service to determine if there is a permission to invoke the interface, we obtain the authentication token information from the request header, do not need to rely on cookies
This filter I also recommend to write in the global project, because also all services are used, code please refer to: httpbasicauthorizefilter
The main logic is to obtain tokens and then through the jwtutils to verify whether legal, illegal to prompt, legal is spared
The point to note here is that the decryption key must be the same as the encryption, or decryption must fail, is the bug
Verify the token
if (! Stringutils.hastext (auth)) {
PrintWriter print = Httpresponse.getwriter ();
Print.write (Jsonutils.tojson (Responsedata.fail ("Illegal request" missing authorization Information "",
responsecode.no_auth_ Code.getcode ())));
return;
}
Jwtutils.jwtresult JWT = Jwtutils.checktoken (auth);
if (!jwt.isstatus ()) {
PrintWriter print = Httpresponse.getwriter ();
Print.write (Jsonutils.tojson (Responsedata.fail (Jwt.getmsg (), Jwt.getcode ()));
return;
}
Chain.dofilter (HttpRequest, response);
To this end, as long as the caller after the authentication pass, the token returned by the authentication service, and then plugged into the request header authorization, you can call other services that require authentication.
This seems to be perfect, but it is inconvenient to use, each call before the need to go to certification, and then plug the request head, how to do general, do not need specific developers to care, transparent to users, the next article, we continue to explore how to achieve convenient invocation.
The specific code can refer to my github:
Https://github.com/yinjihuan/spring-cloud