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

Posted dream_heheda

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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否则会失败。

以上是关于Spring boot + JWT 实现安全验证 ---auth0.jwt的主要内容,如果未能解决你的问题,请参考以下文章

在 Spring Boot 安全性中使用公钥/私钥创建和验证 JWT 签名

架构微服务 Spring Boot

在 Spring Boot 2 上实现基于过滤器的 JWT 身份验证与 OAuth2 JWT 身份验证

无法理解 JWT 和 Java (Spring Boot)。这个应用程序安全吗?

Oauth2 + jwt 和 spring boot

在 Spring Boot 中使用 Keycloak 实现 JWT、JWE 和 JWS(签名 JWT)