Spring boot + JWT 实现安全验证 ---auth0.jwt

参考 http://auth0 / java-jwt

auth0的jwt 实现安全验证: 使用自定义参数 和时间戳生成token。验证token时验证自定义参数。auth0.jwt 验证token时会自动验证时间戳是否过期,如果过期,会抛出异常TokenExpiredException

1.引入依赖

<!-- https://mvnrepository.com/artifact/com.auth0/java-jwt -->
<dependency>
	<groupId>com.auth0</groupId>
	<artifactId>java-jwt</artifactId>
	<version>3.10.3</version>
</dependency>

2.生成token和验证token的工具类

import java.util.Date;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;

@Component
public class TokenUtil {

	@Value("${jwt.issuer}")
	private String ISSUER;//project-name

	@Value("${jwt.audience}")
	private String AUDIENCE;//web

	@Value("${jwt.expires_in}")
	private int EXPIRES_IN;//30

	private String encryKey = "project-name";

	private Algorithm ALGORITHM = Algorithm.HMAC256(encryKey);

	private Logger logger = LoggerFactory.getLogger(this.getClass());

	public static Boolean result = false;
	public static String message = "";

	public String generateToken(String username) {

		
		long currentTime = System.currentTimeMillis();
		logger.info("=====generateToken===now    is " + new Date(currentTime));
		logger.info("=====generateToken===expire is " + new Date(currentTime + EXPIRES_IN * 1000 * 60));

		String token = JWT.create()

				.withIssuer(ISSUER)

				.withIssuedAt(new Date(currentTime))// 签发时间

				.withExpiresAt(new Date(currentTime + EXPIRES_IN * 1000 * 60))// 过期时间戳

				.withClaim("username", username)//自定义参数

				.sign(ALGORITHM);

		return token;
	}

	public void verifyToken(String token) {

		try {

			if (null == token) {
				result = false;
				message = "token is null";
				return;
			}
			// Reusable verifier instance
			JWTVerifier verifier = JWT.require(ALGORITHM)

					.withIssuer(ISSUER)

					.build();
			DecodedJWT decodedJWT = verifier.verify(token);

			// verify issuer
			String issuer = decodedJWT.getIssuer();

			// verity 自定义参数
			String username = decodedJWT.getClaim("username").asString();
			if (("").equals(username)) {
				result = false;
				message = "user is error";
				return;
			}

		} catch (TokenExpiredException e) {
			result = false;
			message = "token is expired";
			return;
		}
		result = true;
		message = "token is verified";

	}

}

3. 把token的生成和验证工具 添加到spring 拦截器中

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

public class TokenInterceptor extends HandlerInterceptorAdapter {

	private TokenHelper tokenHelper;

	public TokenInterceptor(TokenHelper tokenHelper) {
		this.tokenHelper = tokenHelper;
	}

	private Logger logger = LoggerFactory.getLogger(this.getClass());

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {

		// verify token
		tokenHelper.verifyToken(request.getHeader("token"));

		// result
		if (TokenHelper.result) {
			return true;
		} else {
			response.setStatus(403);
			logger.error(TokenHelper.message);
			return false;
		}

	}

}

4.注册拦截器

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {

	@Autowired
	private TokenHelper tokenHelper;

	@Override
	public void addInterceptors(InterceptorRegistry registry) {

		List<String> excludePath = new ArrayList<>();
		// 获取token 不要验证
		excludePath.add("/api/generateToken");

		registry.addInterceptor(new TokenInterceptor(tokenHelper))

				.addPathPatterns("/**")

				.excludePathPatterns(excludePath);
	}

}

5.生成token测试

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api")
public class TokenController {

	@Autowired
	private TokenHelper tokenHelper;

	@PostMapping(value = "/generateToken")
	public String generateToken(@RequestParam("username") String username) {
		return tokenHelper.generateToken(username);

	}

}

6.其它url访问项目 都需要在请求头部带着token否则会失败。

posted on 2020-06-29 15:42  dreamstar  阅读(2757)  评论(0编辑  收藏  举报