解析SpringSecurity+JWT认证流程实现

纸上得来终觉浅,觉知此事要躬行。

楔子

本文适合:对Spring Security有一点了解或者跑过简单demo但是对整体运行流程不明白的同学,对SpringSecurity有兴趣的也可以当作你们的入门教程,示例代码中也有很多注释。

本文代码:码云地址  GitHub地址

大家在做系统的时候,一般做的第一个模块就是认证与授权模块,因为这是一个系统的入口,也是一个系统最重要最基础的一环,在认证与授权服务设计搭建好了之后,剩下的模块才得以安全访问。

市面上一般做认证授权的框架就是shiroSpring Security,也有大部分公司选择自己研制。出于之前看过很多Spring Security的入门教程,但都觉得讲的不是太好,所以我这两天在自己鼓捣Spring Security的时候萌生了分享一下的想法,希望可以帮助到有兴趣的人。

Spring Security框架我们主要用它就是解决一个认证授权功能,所以我的文章主要会分为两部分:

  • 第一部分认证(本篇)
  • 第二部分授权(放在下一篇)

我会为大家用一个Spring Security + JWT + 缓存的一个demo来展现我要讲的东西,毕竟脑子的东西要体现在具体事物上才可以更直观的让大家去了解去认识。

学习一件新事物的时候,我推荐使用自顶向下的学习方法,这样可以更好的认识新事物,而不是盲人摸象。

注:只涉及到用户认证授权不涉及oauth2之类的第三方授权。

1. :book:SpringSecurity的工作流程

想上手 Spring Security 一定要先了解它的工作流程,因为它不像工具包一样,拿来即用,必须要对它有一定的了解,再根据它的用法进行自定义操作。

我们可以先来看看它的工作流程:

Spring Security的官方文档上有这么一句话:

Spring Security's web infrastructure is based entirely on standard servlet filters.

Spring Security 的web基础是Filters。

这句话展示了Spring Security的设计思想:即通过一层层的Filters来对web请求做处理。

放到真实的Spring Security中,用文字表述的话可以这样说:

一个web请求会经过一条过滤器链,在经过过滤器链的过程中会完成认证与授权,如果中间发现这条请求未认证或者未授权,会根据被保护API的权限去抛出异常,然后由异常处理器去处理这些异常。

用图片表述的话可以这样画,这是我在百度找到的一张图片:

如上图,一个请求想要访问到API就会以从左到右的形式经过蓝线框框里面的过滤器,其中绿色部分是我们本篇主要讲的负责认证的过滤器,蓝色部分负责异常处理,橙色部分则是负责授权。

图中的这两个绿色过滤器我们今天不会去说,因为这是Spring Security对form表单认证和Basic认证内置的两个Filter,而我们的demo是JWT认证方式所以用不上。

如果你用过Spring Security就应该知道配置中有两个叫formLoginhttpBasic的配置项,在配置中打开了它俩就对应着打开了上面的过滤器。

  • formLogin对应着你form表单认证方式,即UsernamePasswordAuthenticationFilter。
  • httpBasic对应着Basic认证方式,即BasicAuthenticationFilter。

换言之,你配置了这两种认证方式,过滤器链中才会加入它们,否则它们是不会被加到过滤器链中去的。

因为Spring Security自带的过滤器中是没有针对JWT这种认证方式的,所以我们的demo中会写一个JWT的认证过滤器,然后放在绿色的位置进行认证工作。

2. :memo:SpringSecurity的重要概念

知道了Spring Security的大致工作流程之后,我们还需要知道一些非常重要的概念也可以说是组件:

  • SecurityContext:上下文对象,Authentication对象会放在里面。
  • SecurityContextHolder:用于拿到上下文对象的静态工具类。
  • Authentication:认证接口,定义了认证对象的数据形式。
  • AuthenticationManager:用于校验Authentication,返回一个认证完成后的Authentication对象。

1.SecurityContext

上下文对象,认证后的数据就放在这里面,接口定义如下:

public interface SecurityContext extends Serializable {
 // 获取Authentication对象
 Authentication getAuthentication();

 // 放入Authentication对象
 void setAuthentication(Authentication authentication);
}

这个接口里面只有两个方法,其主要作用就是get or setAuthentication

2. SecurityContextHolder

public class SecurityContextHolder {

 public static void clearContext() {
 strategy.clearContext();
 }

 public static SecurityContext getContext() {
 return strategy.getContext();
 }

  public static void setContext(SecurityContext context) {
 strategy.setContext(context);
 }

}

可以说是SecurityContext的工具类,用于get or set or clearSecurityContext,默认会把数据都存储到当前线程中。

3. Authentication

public interface Authentication extends Principal, Serializable {

 Collection<? extends GrantedAuthority> getAuthorities();
 Object getCredentials();
 Object getDetails();
 Object getPrincipal();
 boolean isAuthenticated();
 void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException;
}

这几个方法效果如下:

  • getAuthorities: 获取用户权限,一般情况下获取到的是用户的角色信息
  • getCredentials: 获取证明用户认证的信息,通常情况下获取到的是密码等信息。
  • getDetails: 获取用户的额外信息,(这部分信息可以是我们的用户表中的信息)。
  • getPrincipal: 获取用户身份信息,在未认证的情况下获取到的是用户名,在已认证的情况下获取到的是 UserDetails。
  • isAuthenticated: 获取当前Authentication是否已认证。setAuthenticated: 设置当前Authentication是否已认证(true or false)。

Authentication只是定义了一种在SpringSecurity进行认证过的数据的数据形式应该是怎么样的,要有权限,要有密码,要有身份信息,要有额外信息。

4. AuthenticationManager

public interface AuthenticationManager {
 // 认证方法
 Authentication authenticate(Authentication authentication)
  throws AuthenticationException;
}

AuthenticationManager定义了一个认证方法,它将一个未认证的Authentication传入,返回一个已认证的Authentication,默认使用的实现类为:ProviderManager。

接下来大家可以构思一下如何将这四个部分,串联起来,构成Spring Security进行认证的流程:

1. :point_right:先是一个请求带着身份信息进来

2. :point_right:经过AuthenticationManager的认证,

3. :point_right:再通过SecurityContextHolder获取SecurityContext

4. :point_right:最后将认证后的信息放入到SecurityContext

3. :page_with_curl:代码前的准备工作

真正开始讲诉我们的认证代码之前,我们首先需要导入必要的依赖,数据库相关的依赖可以自行选择什么JDBC框架,我这里用的是国人二次开发的myabtis-plus。

  <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.springframework.boot</groupId>
      <artifactId>spring-boot-starter-validation</artifactId>
    </dependency>

    <dependency>
      <groupId>io.jsonwebtoken</groupId>
      <artifactId>jjwt</artifactId>
      <version>0.9.0</version>
    </dependency>

    <dependency>
      <groupId>com.baomidou</groupId>
      <artifactId>mybatis-plus-boot-starter</artifactId>
      <version>3.3.0</version>
    </dependency>

    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.47</version>
    </dependency>

接着,我们需要定义几个必须的组件。

由于我用的Spring-Boot是2.X所以必须要我们自己定义一个加密器:

1. 定义加密器Bean

 @Bean
  public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
  }

这个Bean是不必可少的,Spring Security在认证操作时会使用我们定义的这个加密器,如果没有则会出现异常。

2. 定义AuthenticationManager

@Bean
  public AuthenticationManager authenticationManager() throws Exception {
    return super.authenticationManager();
  }

这里将Spring Security自带的authenticationManager声明成Bean,声明它的作用是用它帮我们进行认证操作,调用这个Bean的authenticate方法会由Spring Security自动帮我们做认证。

3. 实现UserDetailsService

public class CustomUserDetailsService implements UserDetailsService {
  @Autowired
  private UserService userService;
  @Autowired
  private RoleInfoService roleInfoService;
  @Override
  public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
    log.debug("开始登陆验证,用户名为: {}",s);

    // 根据用户名验证用户
    QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
    queryWrapper.lambda().eq(UserInfo::getLoginAccount,s);
    UserInfo userInfo = userService.getOne(queryWrapper);
    if (userInfo == null) {
      throw new UsernameNotFoundException("用户名不存在,登陆失败。");
    }

    // 构建UserDetail对象
    UserDetail userDetail = new UserDetail();
    userDetail.setUserInfo(userInfo);
    List<RoleInfo> roleInfoList = roleInfoService.listRoleByUserId(userInfo.getUserId());
    userDetail.setRoleInfoList(roleInfoList);
    return userDetail;
  }
}

实现UserDetailsService的抽象方法并返回一个UserDetails对象,认证过程中SpringSecurity会调用这个方法访问数据库进行对用户的搜索,逻辑什么都可以自定义,无论是从数据库中还是从缓存中,但是我们需要将我们查询出来的用户信息和权限信息组装成一个UserDetails返回。

UserDetails也是一个定义了数据形式的接口,用于保存我们从数据库中查出来的数据,其功能主要是验证账号状态和获取权限,具体实现可以查阅我仓库的代码。

4. TokenUtil

由于我们是JWT的认证模式,所以我们也需要一个帮我们操作Token的工具类,一般来说它具有以下三个方法就够了:

  • 创建token
  • 验证token
  • 反解析token中的信息

在下文我的代码里面,JwtProvider充当了Token工具类的角色,具体实现可以查阅我仓库的代码

4. ✍代码中的具体实现

有了前面的讲解之后,大家应该都知道用SpringSecurity做JWT认证需要我们自己写一个过滤器来做JWT的校验,然后将这个过滤器放到绿色部分。

在我们编写这个过滤器之前,我们还需要进行一个认证操作,因为我们要先访问认证接口拿到token,才能把token放到请求头上,进行接下来请求。

如果你不太明白,不要紧,先接着往下看我会在这节结束再次梳理一下。

1. 认证方法

访问一个系统,一般最先访问的是认证方法,这里我写了最简略的认证需要的几个步骤,因为实际系统中我们还要写登录记录啊,前台密码解密啊这些操作。

@Override
  public ApiResult login(String loginAccount, String password) {
    // 1 创建UsernamePasswordAuthenticationToken
    UsernamePasswordAuthenticationToken usernameAuthentication = new UsernamePasswordAuthenticationToken(loginAccount, password);
    // 2 认证
    Authentication authentication = this.authenticationManager.authenticate(usernameAuthentication);
    // 3 保存认证信息
    SecurityContextHolder.getContext().setAuthentication(authentication);
    // 4 生成自定义token
    UserDetail userDetail = (UserDetail) authentication.getPrincipal();
    AccessToken accessToken = jwtProvider.createToken((UserDetails) authentication.getPrincipal());

    // 5 放入缓存
    caffeineCache.put(CacheName.USER, userDetail.getUsername(), userDetail);
    return ApiResult.ok(accessToken);
  }

这里一共五个步骤,大概只有前四步是比较陌生的:

  • 传入用户名和密码创建了一个UsernamePasswordAuthenticationToken对象,这是我们前面说过的Authentication的实现类,传入用户名和密码做构造参数,这个对象就是我们创建出来的未认证的Authentication对象。
  • 使用我们先前已经声明过的Bean-authenticationManager调用它的authenticate方法进行认证,返回一个认证完成的Authentication对象。
  • 认证完成没有出现异常,就会走到第三步,使用SecurityContextHolder获取SecurityContext之后,将认证完成之后的Authentication对象,放入上下文对象。
  • 从Authentication对象中拿到我们的UserDetails对象,之前我们说过,认证后的Authentication对象调用它的getPrincipal()方法就可以拿到我们先前数据库查询后组装出来的UserDetails对象,然后创建token。
  • 把UserDetails对象放入缓存中,方便后面过滤器使用。

这样的话就算完成了,感觉上很简单,因为主要认证操作都会由authenticationManager.authenticate()帮我们完成。

接下来我们可以看看源码,从中窥得Spring Security是如何帮我们做这个认证的(省略了一部分):

// AbstractUserDetailsAuthenticationProvider

public Authentication authenticate(Authentication authentication){

 // 校验未认证的Authentication对象里面有没有用户名
 String username = (authentication.getPrincipal() == null) ? "NONE_PROVIDED"
  : authentication.getName(); 

   boolean cacheWasUsed = true;
   // 从缓存中去查用户名为XXX的对象
 UserDetails user = this.userCache.getUserFromCache(username);

   // 如果没有就进入到这个方法
 if (user == null) {
  cacheWasUsed = false;

  try {
        // 调用我们重写UserDetailsService的loadUserByUsername方法
        // 拿到我们自己组装好的UserDetails对象
  user = retrieveUser(username,
   (UsernamePasswordAuthenticationToken) authentication);
  }
  catch (UsernameNotFoundException notFound) {
  logger.debug("User '" + username + "' not found");

  if (hideUserNotFoundExceptions) {
   throw new BadCredentialsException(messages.getMessage(
    "AbstractUserDetailsAuthenticationProvider.badCredentials",
    "Bad credentials"));
  }
  else {
   throw notFound;
  }
  }

  Assert.notNull(user,
   "retrieveUser returned null - a violation of the interface contract");
 }

  try {
     // 校验账号是否禁用
  preAuthenticationChecks.check(user);
     // 校验数据库查出来的密码,和我们传入的密码是否一致
  additionalAuthenticationChecks(user,
   (UsernamePasswordAuthenticationToken) authentication);
 }

}

看了源码之后你会发现和我们平常写的一样,其主要逻辑也是查数据库然后对比密码。

登录之后效果如下:

我们返回token之后,下次请求其他API的时候就要在请求头中带上这个token,都按照JWT的标准来做就可以。

2. JWT过滤器

有了token之后,我们要把过滤器放在过滤器链中,用于解析token,因为我们没有session,所以我们每次去辨别这是哪个用户的请求的时候,都是根据请求中的token来解析出来当前是哪个用户。

所以我们需要一个过滤器去拦截所有请求,前文我们也说过,这个过滤器我们会放在绿色部分用来替代UsernamePasswordAuthenticationFilter,所以我们新建一个JwtAuthenticationTokenFilter,然后将它注册为Bean,并在编写配置文件的时候需要加上这个:

@Bean
  public JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter() {
    return new JwtAuthenticationTokenFilter();
  }

@Override
  protected void configure(HttpSecurity http) throws Exception {
    http.addFilterBefore(jwtAuthenticationTokenFilter(),
            UsernamePasswordAuthenticationFilter.class);
  }

addFilterBefore的语义是添加一个Filter到XXXFilter之前,放在这里就是把JwtAuthenticationTokenFilter放在UsernamePasswordAuthenticationFilter之前,因为filter的执行也是有顺序的,我们必须要把我们的filter放在过滤器链中绿色的部分才会起到自动认证的效果。

接下来我们可以看看JwtAuthenticationTokenFilter的具体实现了:

@Override
  protected void doFilterInternal(@NotNull HttpServletRequest request,
                  @NotNull HttpServletResponse response,
                  @NotNull FilterChain chain) throws ServletException, IOException {
    log.info("JWT过滤器通过校验请求头token进行自动登录...");

    // 拿到Authorization请求头内的信息
    String authToken = jwtProvider.getToken(request);

    // 判断一下内容是否为空且是否为(Bearer )开头
    if (StrUtil.isNotEmpty(authToken) && authToken.startsWith(jwtProperties.getTokenPrefix())) {
      // 去掉token前缀(Bearer ),拿到真实token
      authToken = authToken.substring(jwtProperties.getTokenPrefix().length());

      // 拿到token里面的登录账号
      String loginAccount = jwtProvider.getSubjectFromToken(authToken);

      if (StrUtil.isNotEmpty(loginAccount) && SecurityContextHolder.getContext().getAuthentication() == null) {
        // 缓存里查询用户,不存在需要重新登陆。
        UserDetail userDetails = caffeineCache.get(CacheName.USER, loginAccount, UserDetail.class);

        // 拿到用户信息后验证用户信息与token
        if (userDetails != null && jwtProvider.validateToken(authToken, userDetails)) {

          // 组装authentication对象,构造参数是Principal Credentials 与 Authorities
          // 后面的拦截器里面会用到 grantedAuthorities 方法
          UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, userDetails.getPassword(), userDetails.getAuthorities());

          // 将authentication信息放入到上下文对象中
          SecurityContextHolder.getContext().setAuthentication(authentication);

          log.info("JWT过滤器通过校验请求头token自动登录成功, user : {}", userDetails.getUsername());
        }
      }
    }

    chain.doFilter(request, response);
  }

代码里步骤虽然说的很详细了,但是可能因为代码过长不利于阅读,我还是简单说说,也可以直接去仓库查看源码

  • 拿到Authorization请求头对应的token信息
  • 去掉token的头部(Bearer )
  • 解析token,拿到我们放在里面的登陆账号
  • 因为我们之前登陆过,所以我们直接从缓存里面拿我们的UserDetail信息即可
  • 查看是否UserDetail为null,以及查看token是否过期,UserDetail用户名与token中的是否一直。
  • 组装一个authentication对象,把它放在上下文对象中,这样后面的过滤器看到我们上下文对象中有authentication对象,就相当于我们已经认证过了。

这样的话,每一个带有正确token的请求进来之后,都会找到它的账号信息,并放在上下文对象中,我们可以使用SecurityContextHolder很方便的拿到上下文对象中的Authentication对象。

完成之后,启动我们的demo,可以看到过滤器链中有以下过滤器,其中我们自定义的是第5个:

:cat:‍ 就酱,我们登录完了之后获取到的账号信息与角色信息我们都会放到缓存中,当带着token的请求来到时,我们就把它从缓存中拿出来,再次放到上下文对象中去。

结合认证方法,我们的逻辑链就变成了:

登录:point_right:拿到token:point_right:请求带上token:point_right:JWT过滤器拦截:point_right:校验token:point_right:将从缓存中查出来的对象放到上下文中

这样之后,我们认证的逻辑就算完成了。

4. 代码优化

认证和JWT过滤器完成后,这个JWT的项目其实就可以跑起来了,可以实现我们想要的效果,如果想让程序更健壮,我们还需要再加一些辅助功能,让代码更友好。

1. 认证失败处理器

当用户未登录或者token解析失败时会触发这个处理器,返回一个非法访问的结果。

2. 权限不足处理器

当用户本身权限不满足所访问API需要的权限时,触发这个处理器,返回一个权限不足的结果。

3. 退出方法

用户退出一般就是清除掉上下文对象和缓存就行了,你也可以做一下附加操作,这两步是必须的。

4. token刷新

JWT的项目token刷新也是必不可少的,这里刷新token的主要方法放在了token工具类里面,刷新完了把缓存重载一遍就行了,因为缓存是有有效期的,重新put可以重置失效时间。

后记

这篇文我从上周日就开始构思了,为了能讲的老妪能解,修修改改了几遍才发出来。

Spring Security的上手的确有点难度,在我第一次去了解它的时候看的是尚硅谷的教程,那个视频的讲师拿它和Thymeleaf结合,这就导致网上也有很多博客去讲Spring Security的时候也是这种方式,而没有去关注前后端分离。

也有教程做过滤器的时候是直接继承UsernamePasswordAuthenticationFilter,这样的方法也是可行的,不过我们了解了整体的运行流程之后你就知道没必要这样做,不需要去继承XXX,只要写个过滤器然后放在那个位置就可以了。

本文代码:码云地址GitHub地址

到此这篇关于解析SpringSecurity+JWT认证流程实现的文章就介绍到这了,更多相关SpringSecurity+JWT认证内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Springboot+SpringSecurity+JWT实现用户登录和权限认证示例

    如今,互联网项目对于安全的要求越来越严格,这就是对后端开发提出了更多的要求,目前比较成熟的几种大家比较熟悉的模式,像RBAC 基于角色权限的验证,shiro框架专门用于处理权限方面的,另一个比较流行的后端框架是Spring-Security,该框架提供了一整套比较成熟,也很完整的机制用于处理各类场景下的可以基于权限,资源路径,以及授权方面的解决方案,部分模块支持定制化,而且在和oauth2.0进行了很好的无缝连接,在移动互联网的授权认证方面有很强的优势,具体的使用大家可以结合自己的业务场景进行选

  • 解析SpringSecurity+JWT认证流程实现

    纸上得来终觉浅,觉知此事要躬行. 楔子 本文适合:对Spring Security有一点了解或者跑过简单demo但是对整体运行流程不明白的同学,对SpringSecurity有兴趣的也可以当作你们的入门教程,示例代码中也有很多注释. 本文代码:码云地址  GitHub地址 大家在做系统的时候,一般做的第一个模块就是认证与授权模块,因为这是一个系统的入口,也是一个系统最重要最基础的一环,在认证与授权服务设计搭建好了之后,剩下的模块才得以安全访问. 市面上一般做认证授权的框架就是shiro和Spri

  • SpringBoot+SpringSecurity+JWT实现系统认证与授权示例

    目录 1. Spring Security简介 2. JWT简介 3. Spring Boot整合Spring Security 4. 配置Spring Security使用JWT认证 5. 实现登录接口 6. 测试 7. 源码 1. Spring Security简介 Spring Security是Spring的一个核心项目,它是一个功能强大且高度可定制的认证和访问控制框架.它提供了认证和授权功能以及抵御常见的攻击,它已经成为保护基于spring的应用程序的事实标准. Spring Boot

  • SpringBoot整合SpringSecurity实现JWT认证的项目实践

    目录 前言 1.创建SpringBoot工程 2.导入SpringSecurity与JWT的相关依赖 3.定义SpringSecurity需要的基础处理类 4. 构建JWT token工具类 5.实现token验证的过滤器 6. SpringSecurity的关键配置 7. 编写Controller进行测试 前言 微服务架构,前后端分离目前已成为互联网项目开发的业界标准,其核心思想就是前端(APP.小程序.H5页面等)通过调用后端的API接口,提交及返回JSON数据进行交互.在前后端分离项目中,

  • 教你使用springSecurity+jwt实现互踢功能

    jwt介绍:         JWT是一种用于双方之间传递安全信息的简洁的.URL安全的表述性声明规范.JWT作为一个开放的标准( RFC 7519 ),定义了一种简洁的,自包含的方法用于通信双方之间以Json对象的形式安全的传递信息. jwt认证流程介绍: 1. 用户使用账号和面发出post请求:  2. 服务器使用私钥创建一个jwt:  3. 服务器返回这个jwt给浏览器:  4. 浏览器将该jwt串在请求头中像服务器发送请求:  5. 服务器验证该jwt:  6. 返回响应的资源给浏览器.

  • mall整合SpringSecurity及JWT认证授权实战下

    目录 摘要 登录注册功能实现 添加UmsAdminController类 添加UmsAdminService接口 添加UmsAdminServiceImpl类 修改Swagger的配置 给PmsBrandController接口中的方法添加访问权限 认证与授权流程演示 运行项目,访问API 未登录前访问接口 登录后访问接口 访问需要权限的接口 改用其他有权限的帐号登录 摘要 接上一篇,controller和service层的代码实现及登录授权流程演示. 登录注册功能实现 添加UmsAdminCo

  • SpringSecurity认证流程详解

    SpringSecurity基本原理 在之前的文章<SpringBoot + Spring Security 基本使用及个性化登录配置>中对SpringSecurity进行了简单的使用介绍,基本上都是对于接口的介绍以及功能的实现. 这一篇文章尝试从源码的角度来上对用户认证流程做一个简单的分析. 在具体分析之前,我们可以先看看SpringSecurity的大概原理: SpringSecurity基本原理 其实比较简单,主要是通过一系列的Filter对请求进行拦截处理. 认证处理流程说明 我们直接

  • Java SpringSecurity+JWT实现登录认证

    目录 整合步骤 实现原理 目录结构 做了哪些变化 前言: 学习过我的mall项目的应该知道,mall-admin模块是使用SpringSecurity+JWT来实现登录认证的,而mall-portal模块是使用的SpringSecurity基于Session的默认机制来实现登陆认证的.很多小伙伴都找不到mall-portal的登录接口,最近我把这两个模块的登录认证给统一了,都使用SpringSecurity+JWT的形式实现.主要是通过把登录认证的通用逻辑抽取到了mall-security模块来

  • SpringBoot+SpringSecurity+jwt实现验证

    目录 环境 目录结构信息 记录一下使用springSecurity实现jwt的授权方法,这方法可以实现权限的基本认证.当然这个案例还有许多的问题,不过还是先记录一下.其他功能以后在补充. 建议工程创建流程 创建 JwtTokenUtils 创建 jwtAccessDeniedHandler 和 JwtAuthenticationEntryPoint 创建 UserDetailsServiceImpl 创建 JwtAuthenticationFilter 配置 Security信息 启动类的信息

  • SpringSecurity Jwt Token 自动刷新的实现

    功能需求 最近项目中有这么一个功能,用户登录系统后,需要给 用户 颁发一个 token ,后续访问系统的请求都需要带上这个 token ,如果请求没有带上这个 token 或者 token 过期了,那么禁止访问系统.如果用户一直访问系统,那么还需要自动延长 token 的过期时间. 功能分析 1.token 的生成 使用现在比较流行的 jwt 来生成. 2.token 的自动延长 要实现 token 的自动延长,系统给用户 颁发 一个 token 无法实现,那么通过变通一个,给用户生成 2个 t

随机推荐