当前位置: 首页 > article >正文

SpringSecurity基于JWT实现Token的处理

  前面介绍了手写单点登录和JWT的应用,本文结合SpringSecurity来介绍下在SpringBoot项目中基于SpringSecurity作为认证授权框架的情况下如何整合JWT来实现Token的处理。

一、认证思路分析

  SpringSecurity主要是通过过滤器来实现功能的!我们要找到SpringSecurity实现认证和校验身份的过滤器!

1.回顾集中式认证流程

用户认证
  使用 UsernamePasswordAuthenticationFilter过滤器中 attemptAuthentication方法实现认证功能,该过滤器父类中 successfulAuthentication方法实现认证成功后的操作。认证失败是在 unsuccessfulAuthentication

身份校验

  使用 BasicAuthenticationFilter 过滤器中 doFilterInternal方法验证是否登录,以决定能否进入后续过滤器。

2.分析分布式认证流程

用户认证
  由于分布式项目,多数是前后端分离的架构设计,我们要满足可以接受异步post的认证请求参数,需要修改UsernamePasswordAuthenticationFilter过滤器中attemptAuthentication方法,让其能够接收请求体。
  另外,默认successfulAuthentication方法在认证通过后,是把用户信息直接放入session就完事了,现在我们需要修改这个方法,在认证通过后生成token并返回给用户。
身份校验
  原来BasicAuthenticationFilter过滤器中doFilterInternal方法校验用户是否登录,就是看session中是否有用户信息,我们要修改为,验证用户携带的token是否合法,并解析出用户信息,交给SpringSecurity,以便于后续的授权功能可以正常使用。

二、具体实现

1.创建项目

  创建一个SpringBoot项目.引入必要的依赖

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.bobo</groupId>
            <artifactId>security-jwt-common</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.80</version>
        </dependency>
	<dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.4.0</version>
        </dependency>
    </dependencies>

2.JWT工具类

  引入前面创建的JWT的工具类。


import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.AlgorithmMismatchException;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;

import java.security.SignatureException;
import java.util.Calendar;
import java.util.Map;

public class JWTUtils {
   
    // 秘钥
    private static final String SING = "123qwaszx";

    /**
     * 生成Token  header.payload.sing 组成
     * @return
     */
    public static String getToken(Map<String,String> map){
   
        Calendar instance = Calendar.getInstance();
        instance.add(Calendar.DATE,7); // 默认过期时间 7天
        JWTCreator.Builder builder = JWT.create();
        // payload 设置
        map.forEach((k,v)->{
   
            builder.withClaim(k,v);
        });
        // 生成Token 并返回
        return builder.withExpiresAt(instance.getTime())
                .sign(Algorithm.HMAC256(SING));
    }

    /**
     * 验证Token
     * @return
     *     DecodedJWT  可以用来获取用户信息
     */
    public static DecodedJWT verify(String token){
   
        // 如果不抛出异常说明验证通过,否则验证失败
        DecodedJWT verify = null;
        try {
   
            verify = JWT.require(Algorithm.HMAC256(SING)).build().verify(token);
        }catch (SignatureVerificationException e){
   
            e.printStackTrace();
        }catch (AlgorithmMismatchException e){
   
            e.printStackTrace();
        }catch (Exception e){
   
            e.printStackTrace();
        }
        return verify;
    }
}

3.用户实例

  创建用户的实例,添加必要的属性

@Data
public class UserPojo implements UserDetails {
   

    private Integer id;

    private String username;

    private String password;

    private Integer status;


    @JsonIgnore
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
   
        List<SimpleGrantedAuthority> auth = new ArrayList<>();
        auth.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
        return auth;
    }

    @Override
    public String getPassword() {
   
        return this.password;
    }

    @Override
    public String getUsername() {
   

http://www.kler.cn/a/569651.html

相关文章:

  • 基于SpringBoot的“青少年心理健康教育网站”的设计与实现(源码+数据库+文档+PPT)
  • 实体机器人识别虚拟环境中障碍物
  • 25环境工程研究生复试面试问题汇总 环境工程专业知识问题很全! 环境工程复试全流程攻略 环境工程考研复试调剂真题汇总
  • onerror事件的理解与用法
  • 《基于Django和ElasticSearch的学术论文搜索推荐系统的设计与实现》开题报告
  • 力扣热题 100:矩阵专题四道题详细解析(JAVA)
  • C语言:51单片机 基础知识
  • 题解 | 牛客周赛83 Java ABCDEF
  • vector 面试点总结
  • RagFlow专题二、RagFlow 核心架构(数据检索、语义搜索与知识融合)
  • HTML——标题标签与段落标签
  • 【力扣】堆相关总结
  • Rust ~ Collect
  • 请求Geoserver的WTMS服务返回200不返回图片问题-跨域导致
  • 基于springboot的酒店客房管理系统----数据库课程设计
  • Vue3核心编译库@vuecompiler-core内容分享
  • 【Qt QML】布局管理
  • QT播放视频保持视频宽高比消除黑边
  • 人工智能丨ChatGPT 免费开放网络搜索,能否挑战 Google 的搜索霸主地位?
  • (十 五)趣学设计模式 之 命令模式!