SpringBook Miscellaneous Notes - User Authentication Using JWT

Last article Introduced in JWT (JSON WEB TOKEN), this article describes how to use it in engineering. JWT.

We can see on the official website that many warehouses have been packaged. JWT Here we chose the first java-jwt

<!-- JSONWEBTOKEN -->
<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.8.1</version>
</dependency>

Recall the introduction of JWT, step one: issuing token to the user at the location of the authenticated user (login), and step two: validating token when the user accesses resources (data) that require authentication privileges

Issue token

When issuing tokens to verify user information, sometimes key operations need to be issued separately to verify. For example, users need to verify user information issuing one-time token separately when they operate some destruction of resources and pay for it.

	// Authorization request/response header field
	public static final String HEADER_AUTHORIZATION = "Authorization";
	
	// secret must not be known to others
	public static final String JWT_SECRET = "YebNZYFXAL1qUjX8516Mi";
	
	// Issuer
    public static final String JWT_ISSUER = "auth0";

	/**
     * Sign in
     */
    @PostMapping("/login")
    public Rs login() {

        String username = requireStringParam("username");
        String password = requireStringParam("password");

        User checkByName = userService.findByName(username);
        if(null == checkByName) {
            throw new InvokeException(Rs.ERROR_CODE_BIZ, "This account has not been registered yet, please register first!");
        }
        User user = new User();
        user.setUserName(username);
        user.setPassword(DigestUtils.md5DigestAsHex(password.getBytes()));
        User loginUser = userService.login(user);

        if(null == loginUser) {
            // Here you can make an error number and put it in session or memory, which is convenient for login restriction.
            throw new InvokeException(Rs.ERROR_CODE_UNAUTHORIZED, "Error in username or password.");
        }

        // Generating token information
        Algorithm algorithm = Algorithm.HMAC256(JWT_SECRET);
        Date expireTime = new Date();
        expireTime.setTime(expireTime.getTime() + 1000*60*30); // Semih.
        String token = JWT.create()
                .withIssuer(JWT_ISSUER) // Issuer
                .withExpiresAt(expireTime) // Expiration date
                .withClaim("username", loginUser.getUserName()) // Current login username
                .withClaim("id", loginUser.getId()) // User number
                .sign(algorithm);
        // Put the signed token in the response header, or, of course, in the Cookie or the response object.
        response.setHeader(HEADER_AUTHORIZATION, "Bearer " + token);
        return Rs.ok(loginUser, "Login successfully");
    }

When the access to the login interface is successful, the Authorization field will appear in the response header.

Verify token

	/**
	 * test AuthorizationInterceptor
	 */
	@RequestMapping(value = "/auth", method = RequestMethod.GET)
	@ResponseBody
	Rs auth() {
		String authorization = request.getHeader(HEADER_AUTHORIZATION);
        if(StringHelper.isEmpty(authorization)) {
            throw new InvokeException(Rs.ERROR_CODE_UNAUTHORIZED, "no authorization.");
        }
        String token = authorization.replace("Bearer ", "");
        Algorithm algorithm = Algorithm.HMAC256(JWT_SECRET);
        JWTVerifier verifier = JWT.require(algorithm)
                .withIssuer(Constans.JWT_ISSUER)
                .build(); //Reusable verifier instance
		// Here, verify(token) verifies that token's signature is not correct and that token expires.
        DecodedJWT jwt = verifier.verify(token);
        String username = jwt.getClaim("username").asString();
        String id = jwt.getClaim("id").asString();
		
		logger.info("[Current user]" + username);
		return Rs.ok("Authorized pass!");
	}

Incidentally update the global exception capture class

/**
 * Exception capture processing class
 */
@ControllerAdvice
public class WebExceptionHandler {

	private Logger logger = LoggerFactory.getLogger(WebExceptionHandler.class);

	@ExceptionHandler(value = Exception.class)
	@ResponseBody
	public Rs errorHandler(HttpServletRequest req, HttpServletResponse res, Exception e) {
		logger.error("", e);
		if (e instanceof InvokeException) {
			InvokeException ex = (InvokeException)e;
			return Rs.err(ex.getErr(), ex.getMessage());
		} else if (e instanceof TokenExpiredException) {
			res.setHeader(Constans.HEADER_AUTHORIZATION, null);
			return Rs.err(Rs.ERROR_CODE_AUTHORIZED_TIMEOUT, "The session has expired, please log in again!");
		} else if (e instanceof JWTVerificationException) {
			return Rs.err(Rs.ERROR_CODE_UNAUTHORIZED, "Error validating authorization!");
		}
		return Rs.errMsg("System error");
	}
}

Verifying user token is a common step, so this part of the code should be written to the interceptor, which is written directly to the business method for convenience. The implementation in the code factory library is written in the interceptor. Interested children's boots can see:

GitHub

PlayWithSpringBoot

Tags: Java Session JSON github

Posted on Sat, 12 Oct 2019 14:41:15 -0700 by texerasmo