This is the 25th day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021

Antecedents to review

In the last article, we talked about why we chose JWT to achieve unified authentication and authorization. Its advantages are more in line with the formation of the initial project, and it can also enhance the user experience through double token. And these paper talk about the past, it is how to achieve these.

This article shows you how to use JWT for unified authorization in a SpringCloud project.

Use JWT for encryption and decryption

We need to do some research on JWT technology before integrating into a SpringCloud project, but to what extent do we need to research the basics of integration?

If you ask me, I will tell you that at the very least, JWT token encryption and decryption should be clear, or debugging should be successful, before it can be integrated into SpringCloud.

The preparatory work

First we need to provide a key, through this key for encryption and decryption.

JWT encryption

Post code directly:

String key = Base64.getEncoder().encodeToString("zhegekeysuibianshejijiuxingkannixinqing".getBytes(Charsets.UTF_8));
// User information
Map<String,String> map = new HashMap<>();
map.put("userId"."zhangsan");
/ / encryption
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
byte[] apiKeySecretBytes = Base64.getDecoder().decode(key);
Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());
JwtBuilder builder = Jwts.builder().signWith(signingKey);
map.forEach(builder::claim);
/ / output token
System.out.println(builder.compact());
Copy the code

Based on the above code, we generate a large list of tokens as shown below.

JWT decryption

Decryption, in fact, is the token to resolve the corresponding user information.

Claims claims = Jwts.parserBuilder().setSigningKey(Base64.getDecoder().decode(JwtUtil.key)).build()
      .parseClaimsJws(token).getBody();
System.out.println(claims.get("userId"));
Copy the code

The following figure can be obtained:

Integrate JWT into the Gateway

Login authentication

We write a LoginController.java class in the Controller layer, in which we write an API to get tokens.

@RestController
public class LoginController {

    @PostMapping("/token")
    public R<AuthInfo> token(@RequestParam(required = false) String account,
                                      @RequestParam(required = false) String password) {
        Map<String,String> map = new HashMap<>(16);
        map.put("account", account);
        map.put("password", password);
        String token = JwtUtil.createJwt(map);
        if (userInfo == null || userInfo.getUser() == null || userInfo.getUser().getId() == null) {
            return R.fail();
        }
        returnR.success(token); }}Copy the code

Write filters to validate tokens

Now that we have the API interface for logging in to obtain tokens, we need to filter all URL links we visit.

So let’s write an authentication filter.

public class AuthFilter implements GlobalFilter, Ordered { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { String path = exchange.getRequest().getURI().getPath(); ServerHttpResponse resp = exchange.getResponse(); String headerToken = exchange.getRequest().getHeaders().getFirst("auth"); If (stringutils. isBlank(headerToken)) {return unAuth(resp, "missing token, authentication failed "); } Claims claims = JwtUtil.parseJWT(headerToken); If (claims == null) {return unAuth(resp, "claims not authorised "); } return chain.filter(exchange); } @Override public int getOrder() { return -99; }}Copy the code

conclusion

The integration of unified authentication and authorization in Gateway is one of the functions that must be integrated in micro-service network. The importance is self-evident and we hope that you can pay attention to it.