1、pom.xml文件配置
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.0</version>
</dependency>
2、验证检查解析Token的代码(TokenHelper)
import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import java.util.Date; import java.util.HashMap; import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.stereotype.Component; import com.test.dfx.common.TimeProvider; import com.test.dfx.model.LicenseDetail; import com.test.dfx.model.User; @Component public class TokenHelper { protected final Log LOGGER = LogFactory.getLog(getClass()); @Value("${app.name}") private String APP_NAME; @Value("${jwt.secret}") public String SECRET; // 用于生成密钥的密钥。从属性文件得到它 @Value("${jwt.expires_in}") private int EXPIRES_IN; // can specify time for token to expire. @Value("${jwt.header}") private String AUTH_HEADER; @Autowired TimeProvider timeProvider; private SignatureAlgorithm SIGNATURE_ALGORITHM = SignatureAlgorithm.HS512; // JWT Algorithm for encryption public Date getIssuedAtDateFromToken(String token) { Date issueAt; try { final Claims claims = this.getAllClaimsFromToken(token); issueAt = claims.getIssuedAt(); } catch (Exception e) { LOGGER.error("Could not get IssuedDate from passed token"); issueAt = null; } return issueAt; } public String getAudienceFromToken(String token) { String audience; try { final Claims claims = this.getAllClaimsFromToken(token); audience = claims.getAudience(); } catch (Exception e) { LOGGER.error("Could not get Audience from passed token"); audience = null; } return audience; } public String refreshToken(String token) { String refreshedToken; Date a = timeProvider.now(); try { final Claims claims = this.getAllClaimsFromToken(token); claims.setIssuedAt(a); refreshedToken = Jwts.builder() .setClaims(claims) .setExpiration(generateExpirationDate()) .signWith( SIGNATURE_ALGORITHM, SECRET ) .compact(); } catch (Exception e) { LOGGER.error("Could not generate Refresh Token from passed token"); refreshedToken = null; } return refreshedToken; } public String generateToken(String username) { String audience = generateAudience(); return Jwts.builder() .setIssuer( APP_NAME ) .setSubject(username) .setAudience(audience) .setIssuedAt(timeProvider.now()) .setExpiration(generateExpirationDate()) .signWith( SIGNATURE_ALGORITHM, SECRET ) .compact(); } private Claims getAllClaimsFromToken(String token) { Claims claims; try { claims = Jwts.parser() .setSigningKey(SECRET) .parseClaimsJws(token) .getBody(); } catch (Exception e) { LOGGER.error("Could not get all claims Token from passed token"); claims = null; } return claims; } private Date generateExpirationDate() { long expiresIn = EXPIRES_IN; return new Date(timeProvider.now().getTime() + expiresIn * 1000); } public int getExpiredIn() { return EXPIRES_IN; } public Boolean validateToken(String token, UserDetails userDetails) { User user = (User) userDetails; final String username = getUsernameFromToken(token); final Date created = getIssuedAtDateFromToken(token); return ( username != null && username.equals(userDetails.getUsername()) && !isCreatedBeforeLastPasswordReset(created, user.getLastPasswordResetDate()) ); } private Boolean isCreatedBeforeLastPasswordReset(Date created, Date lastPasswordReset) { return (lastPasswordReset != null && created.before(lastPasswordReset)); } public String getToken( HttpServletRequest request ) { /** * Getting the token from Authentication header * e.g Bearer your_token */ String authHeader = getAuthHeaderFromHeader( request ); if ( authHeader != null && authHeader.startsWith("Bearer ")) { return authHeader.substring(7); } return null; } public String getAuthHeaderFromHeader( HttpServletRequest request ) { return request.getHeader(AUTH_HEADER); } }
3、Spring Security 代码中添加JWT验证
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.sessionManagement().sessionCreationPolicy( SessionCreationPolicy.STATELESS ).and()
.exceptionHandling().authenticationEntryPoint( restAuthenticationEntryPoint ).and()
.authorizeRequests()
.antMatchers("/auth/**").permitAll()
.antMatchers("/login").permitAll()
.antMatchers("/home").permitAll()
.antMatchers("/actuator/**").permitAll()
.anyRequest().authenticated().and()
.addFilterBefore(new TokenAuthenticationFilter(tokenHelper, jwtUserDetailsService), BasicAuthenticationFilter.class);
http.csrf().disable();
}
4、权限登陆验证过滤器(TokenAuthenticationFilter)
验证每次会话的token
package com.test.dfx.security; import java.io.IOException; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.web.filter.OncePerRequestFilter; public class TokenAuthenticationFilter extends OncePerRequestFilter { protected final Log logger = LogFactory.getLog(getClass()); private TokenHelper tokenHelper; private UserDetailsService userDetailsService; public TokenAuthenticationFilter(TokenHelper tokenHelper, UserDetailsService userDetailsService) { this.tokenHelper = tokenHelper; this.userDetailsService = userDetailsService; } @Override public void doFilterInternal( HttpServletRequest request, HttpServletResponse response, FilterChain chain ) throws IOException, ServletException { String username; String authToken = tokenHelper.getToken(request); logger.info("AuthToken: "+authToken); if (authToken != null) { // get username from token username = tokenHelper.getUsernameFromToken(authToken); logger.info("UserName: "+username); if (username != null) { // get user UserDetails userDetails = userDetailsService.loadUserByUsername(username); if (tokenHelper.validateToken(authToken, userDetails)) { // 创建身份验证 TokenBasedAuthentication authentication = new TokenBasedAuthentication(userDetails); authentication.setToken(authToken); SecurityContextHolder.getContext().setAuthentication(authentication); } }else{ logger.error("Something is wrong with Token."); } } chain.doFilter(request, response); } }