SpringSecurity集成JWT认证框架

1. JWT

        JWT简称JSON Web Token,也就是通过JSON形式作为Web应用中的令牌,用于在各方之间安全地将信息作为JSON对象传输。在数据传输过程中还可以完成数据加密、签名等相关处理。

        JWT的由,header(标头),payload(有效载荷),singnature(签名),三个部分组成的一个Stirng类型的字符串。可以通过对字符串的编码和解密,完成WEB端的登录认证和授权。

        JWT的工作流程如下图所示。

        JWT实现的核心代码有两个,一个是实现拦截器接口,一个是将拦截器注入Spring容器中运行。

        以下是实现拦截器接口,方法是重写前置拦截器,从请求头中获取token的数据进行判断,数据无误可放行,数据不对进行拦截。

public class JWTInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //获取请求头中令牌
        String token = request.getHeader("token");
        try {
            JWTUtils.verify(token);//验证令牌
            return true;//放行请求
        }catch (Exception e){
            e.printStackTrace();
        }
        return false;
    }
}

将拦截器注入Spring容器中,下面需要配置将JWT拦截器进行添加,然后添加下面需要拦截的路径和不需要拦截的路劲。

public class InterceptorConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new JWTInterceptor())
                .addPathPatterns("/user/test")         //其他接口token验证
                .excludePathPatterns("/user/login");  //排除拦截路径
    }
}

2. SpringSecurity

        SpringSecurity是一个安全框架,它有认证授权这两个核心功能。

        用户认证指的是:验证某个用户是否为系统中的合法主体,也就是说用户能否访问该系统。用户认证一般要求用户提供用户名和密码。系统通过校验用户名和密码来完成认证过程。通俗点说就是系统认为用户是否能登录。

        用户授权指的是验证某个用户是否有权限执行某个操作。在一个系统中,不同用户所具有的权限是不同的。比如对一个文件来说,有的用户只能进行读取,而有的用户可以进行修改。一般来说,系统会为不同的用户分配不同的角色,而每个角色则对应一系列的权限。通俗点讲就是系统判断用户是否有权限去做某些事情。

        SpringSecurity有三个重要个实现类和一个接口,我们可以通过重写实现类里面的方法对SpringSecurity进行的配置。他们的调用流程如下。

        第一个类名是UsernamePasswordAuthenticationFilter的过滤器,这个可以通过这个这类获取登录页面提交的账号和密码进行处理,并且可以配置方法的成功和失败。

public class TokenLoginFilter extends UsernamePasswordAuthenticationFilter {

    public TokenLoginFilter() {
        this.setPostOnly(false);
        this.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/admin/acl/login","POST"));
    }
    
	//1 获取表单提交用户名和密码
    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
            throws AuthenticationException {
        //获取表单提交数据
        User user = new ObjectMapper().readValue(request.getInputStream(), User.class);
        return authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(user.getUsername(),user.getPassword(),
                    new ArrayList<>()));
    }
    
	//2 认证成功调用的方法
    @Override
    protected void successfulAuthentication(HttpServletRequest request, 
                                            HttpServletResponse response, FilterChain chain, Authentication authResult)
            throws IOException, ServletException {
        //认证成功,得到认证成功之后用户信息
        //设置token或者设置cookie都在这
    }

    //3 认证失败调用的方法
    @Override
    protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed)
            throws IOException, ServletException {
    }
    
}

        第二个接口是UserDetailsServie的接口,这是接口是SrpingSecurity的用户数据认证接口,需要重写里面的loadUserByUsername方法,在数据库中找到相应的用户数据,复制到UserDetails的类型中返回,就可以对账号就行认证。

public class UserDetailsServiceImpl implements UserDetailsService {

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //根据用户名查询数据
        //将数据库的数据复制到UserDetails的类型中
        UserDetails userDetails = new UserDetails();
        return userDetails;
    }

第三个类是BasicAuthenticationFilter的实现类,重写doFilterInternal方法,这个就是配置权限的方法了,除了登录方法排除在外,其他方法都会进入到这个方法加载权限。然后SpringSecurity就会根据这个权限来判断请求的方法是否可以继续访问。

public class TokenAuthFilter extends BasicAuthenticationFilter {
     @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        //获取当前认证成功用户权限信息
        UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken();
        //判断如果有权限信息,放到权限上下文中
        SecurityContextHolder.getContext().setAuthentication(authRequest);
        
        chain.doFilter(request,response);
    }
}

        第四个配置类是WebSecurityConfigurerAdapter对SpringSecurity进行注入到Spring的容器中运行,需要重写configure的方法,配置数据。

public class TokenWebSecurityConfig extends WebSecurityConfigurerAdapter {
     @Override
    protected void configure(HttpSecurity http) throws Exception {
        //配置特定权限
        http.authorizeRequests()
                .antMatchers("/admin/acl/user/**").hasAuthority("user.list")
             //没有权限访问   
            .and().exceptionHandling()
                .authenticationEntryPoint(new UnauthEntryPoint())
                //跨域问题
            .and().csrf().disable()
               //退出路径 
            .authorizeRequests()
                .anyRequest().authenticated()
                .and().logout().logoutUrl("/admin/acl/index/logout")
                .addLogoutHandler(new TokenLogoutHandler(tokenManager,redisTemplate))
                //添加自定义过滤器
            .and().addFilter(new TokenLoginFilter(authenticationManager(), tokenManager, redisTemplate))
                .addFilter(new TokenAuthFilter(authenticationManager(), tokenManager, redisTemplate)).httpBasic();
    }
}

3.集成JWT

        SpringSecurity+jwt的集成,登录的整个流程。

        集成jwt就是在SpringSecurity架构认证成功之后去添加token返回给前端,这个认证成功的方法就是successfulAuthentication,在这里去添加token返回。

    protected void successfulAuthentication(HttpServletRequest request, 
                                            HttpServletResponse response, FilterChain chain, Authentication authResult)
            throws IOException, ServletException {
        //认证成功,得到认证成功之后用户信息
        SecurityUser user = (SecurityUser)authResult.getPrincipal();
        //根据用户名生成token
        String token = tokenManager.createToken(user.getCurrentUserInfo().getUsername());
        //把用户名称和用户权限列表放到redis
        redisTemplate.opsForValue().set(user.getCurrentUserInfo().getUsername(),user.getPermissionValueList());
        //返回token
        ResponseUtil.out(response, R.ok().data("token",token));
    }

        返回给前端后,前端会将token设置在请求头,之后在每次请求都会发送回来。我们可以在授权前对token进行校验,看是否授权。

protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        //获取当前认证成功用户权限信息
        UsernamePasswordAuthenticationToken authRequest = getAuthentication(request);
        //判断如果有权限信息,放到权限上下文中
        if(authRequest != null) {
            SecurityContextHolder.getContext().setAuthentication(authRequest);
        }
        chain.doFilter(request,response);
    }

private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request) {
        //从header获取token
        String token = request.getHeader("token");
        if(token != null) {
            //从token获取用户名
            String username = tokenManager.getUserInfoFromToken(token);
            //从redis获取对应权限列表
            List<String> permissionValueList = (List<String>)redisTemplate.opsForValue().get(username);
            Collection<GrantedAuthority> authority = new ArrayList<>();
            for(String permissionValue : permissionValueList) {
                SimpleGrantedAuthority auth = new SimpleGrantedAuthority(permissionValue);
                authority.add(auth);
            }
            return new UsernamePasswordAuthenticationToken(username,token,authority);
        }
        return null;
    }

4. 附件

  1. 资源文件:百度云
  2. 不清楚的可以看视频

bilibili htmicon-default.png?t=M85Bhttps://player.bilibili.com/player.html?aid=202502517&bvid=BV15a411A7kP&cid=256421944&page=1

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring SecurityJWT(JSON Web Token)是一种常见的组合,用于实现身份验证和授权机制。 JWT是一种轻量级的身份验证和授权的解决方案,它使用JSON格式来定义安全声明。JWT通常由三部分组成:头部(Header)、载荷(Payload)和签名(Signature)。头部包含算法和令牌类型等信息,载荷包含用户身份和其他相关信息,签名用于验证令牌的完整性和真实性。 Spring Security提供了对JWT的支持,并可以与Spring Boot框架无缝集成。您可以通过以下步骤来实现Spring Security + JWT集成: 1. 添加依赖:在项目的构建文件中,添加Spring SecurityJWT相关的依赖,如spring-boot-starter-security和jjwt。 2. 配置Spring Security:创建一个继承自WebSecurityConfigurerAdapter的配置类,并重写configure方法来配置Spring Security。在该方法中,您可以定义身份验证和授权规则。 3. 创建JWT工具类:创建一个JWT工具类,用于生成、解析和验证JWT。您可以使用jjwt库来处理JWT操作。 4. 实现用户认证:在Spring Security配置类中,您可以实现UserDetailsService接口,并重写loadUserByUsername方法来根据用户名加载用户信息。在该方法中,您可以从数据库或其他数据源中获取用户信息,并构建一个UserDetails对象返回。 5. 实现JWT过滤器:创建一个自定义的过滤器,用于解析和验证传入请求中的JWT。在该过滤器中,您可以使用JWT工具类来解析JWT,并将用户信息添加到Spring Security的上下文中。 6. 配置Spring Security过滤器链:在Spring Security配置类中,将JWT过滤器添加到过滤器链中,以确保每个请求都经过JWT验证。 通过以上步骤,您可以实现Spring SecurityJWT集成,实现基于JWT的身份验证和授权机制。这样,您可以使用JWT生成和验证令牌,并通过Spring Security保护您的应用程序资源。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值