前后端分离的Web应用程序中使用Spring Security+Mybatis+JWT非对称加密+动态权限管理(六):身份验证过滤器

2021/6/10 12:23:13

本文主要是介绍前后端分离的Web应用程序中使用Spring Security+Mybatis+JWT非对称加密+动态权限管理(六):身份验证过滤器,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

在安全配置文件MySecurityConfig.java里配置了两个过滤器LoginFilter和JwtAuthenticationTokenFilter。

1、用户请求进来时,首先调用JwtAuthenticationTokenFilter过滤器,检查是否携带token,如果已有token,则验证token是否合法,如果合法,则直接通过验证。如果没有携带token,或者token不合法,则会进入下一个过滤器,即身份验证过滤器。以下是JwtAuthenticationTokenFilter过滤器代码:

package com.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.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import com.service.MyUserDetailsService;

@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter{
    @Autowired
    MyUserDetailsService userDetailsService;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {

        //请求头为 Authorization
        //请求体为 Bearer token
        String authHeader = request.getHeader("Authorization");  //获取请求头
        if (authHeader != null && authHeader.startsWith("Bearer ")) {  //如果请求头不为空,且以Bearer 开头

            final String authToken = authHeader.substring("Bearer ".length());  //获取令牌

            String username = JwtTokenUtils.parseToken(authToken);  //从令牌中获取用户名
            if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {  //如果用户认证信息不为空
                UserDetails userDetails = userDetailsService.loadUserByUsername(username);
                if (userDetails != null) {
                    UsernamePasswordAuthenticationToken authentication =
                            new UsernamePasswordAuthenticationToken(userDetails, userDetails.getPassword(), userDetails.getAuthorities());
                    authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                    SecurityContextHolder.getContext().setAuthentication(authentication);
                }
            }
        }
        chain.doFilter(request, response);  //请求头为空,或重新认证不通过,则直接进入下一个过滤链
    }

}
View Code

2、用户第一次登录时(无token)或者token不合法时,将调用身份验证过滤器,即LoginFilter。

package com.security;

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

import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

public class LoginFilter extends UsernamePasswordAuthenticationFilter{
    String username;
    String password;
    
    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
            UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(
                    username, password);
            setDetails(request, authRequest);
                return this.getAuthenticationManager().authenticate(authRequest);            
        
    }
}
View Code

身份验证主要是通过改写Authentication方法,通过以下3行代码即完成用户名和密码校验,这是标准的身份校验方法,切不可直接根据加密算法算出加密密文,然后再比较密文是否与数据库中的密文相同这样的方法。

UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
setDetails(request, authRequest);
return this.getAuthenticationManager().authenticate(authRequest);

 



这篇关于前后端分离的Web应用程序中使用Spring Security+Mybatis+JWT非对称加密+动态权限管理(六):身份验证过滤器的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程