SpringSecurity框架中的AbstractAuthenticationProcessingFilter类中
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
Authentication authResult) throws IOException, ServletException {
//认证成功把认证对象信息放在安全上下文中,以便其他过滤器使用
SecurityContextHolder.getContext().setAuthentication(authResult);
if (this.logger.isDebugEnabled()) {
this.logger.debug(LogMessage.format("Set SecurityContextHolder to %s", authResult));
}
this.rememberMeServices.loginSuccess(request, response, authResult);
if (this.eventPublisher != null) {
this.eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(authResult, this.getClass()));
}
this.successHandler.onAuthenticationSuccess(request, response, authResult);
}
SpringSecurity框架中是基于cookie/session技术保存http状态的,cookie/session技术有占用服务端资源等弊端,这里用JWT来代替
创建com.itheima.security.utils.JwtTokenUtil
package com.itheima.security.utils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* @author Piconjo
* @date 2020/5/19 16:38
*/
public class JwtTokenUtil {
// Token请求头
public static final String TOKEN_HEADER = "authorization";
// Token前缀
public static final String TOKEN_PREFIX = "Bearer ";
// 签名主题
public static final String SUBJECT = "JRZS";
// 过期时间
public static final long EXPIRITION = 1000 * 60 * 60* 24 * 7;
// 应用密钥
public static final String APPSECRET_KEY = "itheima";
// 角色权限声明
private static final String ROLE_CLAIMS = "role";
/**
* 生成Token
*/
public static String createToken(String username,String role) {
Map<String,Object> map = new HashMap<>();
map.put(ROLE_CLAIMS, role);
String token = Jwts
.builder()
.setSubject(username)
.setClaims(map)
.claim("username",username)
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + EXPIRITION))
.signWith(SignatureAlgorithm.HS256, APPSECRET_KEY).compact();
return token;
}
/**
* 校验Token
*/
public static Claims checkJWT(String token) {
try {
final Claims claims = Jwts.parser().setSigningKey(APPSECRET_KEY).parseClaimsJws(token).getBody();
return claims;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 从Token中获取用户名
*/
public static String getUsername(String token){
Claims claims = Jwts.parser().setSigningKey(APPSECRET_KEY).parseClaimsJws(token).getBody();
return claims.get("username").toString();
}
/**
* 从Token中获取用户角色
*/
public static String getUserRole(String token){
Claims claims = Jwts.parser().setSigningKey(APPSECRET_KEY).parseClaimsJws(token).getBody();
return claims.get("role").toString();
}
/**
* 校验Token是否过期
*/
public static boolean isExpiration(String token){
Claims claims = Jwts.parser().setSigningKey(APPSECRET_KEY).parseClaimsJws(token).getBody();
return claims.getExpiration().before(new Date());
}
}
生成token,把用户的用户名和权限信息放置在token中响应给前端,在自定义拦截器MyUsernamePasswordAuthenticationFilter中修改代码
@Override
//认证成功时的回调方法
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
User user = (User) authResult.getPrincipal();
String username = user.getUsername();
Collection<GrantedAuthority> authorities = user.getAuthorities();
//生成token
String tokenStr = JwtTokenUtil.createToken(username, authorities.toString());
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
response.setCharacterEncoding("UTF-8");
Map<String,String> info = new HashMap<>();
info.put("msg","登陆成功");
info.put("code","1");
//返回token给前端
info.put("data",tokenStr);
response.getWriter().write(new ObjectMapper().writeValueAsString(info));
}
测试