SpringSecurity+JWT 登录授权过滤器
每次请求都会”携带“ token( token 在 request 的 header 里面)
拦截验证过程:
request -> header -> token -> username -> userDetails(getAuthentication()) -> authentication
SecurityContextHolder.getContext().setAuthentication(authentication) //建立安全上下文
代码
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter { private static final Logger LOGGER = LoggerFactory.getLogger(JwtAuthenticationTokenFilter.class); @Autowired private UserDetailsService userDetailsService; @Autowired private JwtTokenUtil jwtTokenUtil; @Value("${jwt.tokenHeader}") private String tokenHeader; @Value("${jwt.tokenHead}") private String tokenHead; @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException,IOException { //request 中获取去 header String authHeader = request.getHeader(this.tokenHeader); //对header做判断 if (authHeader != null && authHeader.startsWith(this.tokenHeader)) { //取出header //此处注意token之前有一个7字符长度的“Bearer “, String authToken = authHeader.substring(this.tokenHeader.length());// The part after "Bearer " //token中获取username String username = jwtTokenUtil.getUserNameFromToken(authToken); LOGGER.info("checking username:{}", username); //判断username if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) { //拿到userDetails UserDetails userDetails = this.userDetailsService.loadUserByUsername(username); //验证token if (jwtTokenUtil.validateToken(authToken,userDetails)) { //完整填充的 authentication(其中包含了权限集 getAuthorities()) UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken( userDetails, null, userDetails.getAuthorities()); authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); LOGGER.info("authenticated user:{}", username); //建立安全上下文 SecurityContextHolder.getContext().setAuthentication(authentication); } } } chain.doFilter(request, response); } }
UserDetails
public interface UserDetails extends Serializable { //用户的权限集, Collection<? extends GrantedAuthority> getAuthorities(); //用户的加密后的密码, 不加密会使用`{noop}`前缀 String getPassword(); //应用内唯一的用户名 String getUsername(); //账户是否过期 boolean isAccountNonExpired(); //账户是否锁定 boolean isAccountNonLocked(); //凭证是否过期 boolean isCredentialsNonExpired(); //用户是否可用 boolean isEnabled(); }