SpringSecurity 实战项目(四)——Redis+解决Session共享问题

上一篇博客 SpringSecurity 实战项目(三)——动态管理Restful风格权限+JWT+单点登录它支持restful风格的接口权限管理,也可以区分客户端的请求方式。

本片博客添加了redis,本篇博客将在SpringSecurity 实战项目(三)——动态管理Restful风格权限+JWT+单点登录的基础上进行修改使其支持redis 的身份管理。


源码地址:

源码地址:https://gitee.com/zenghua3300/SpringSecurity
喜欢的小伙伴麻烦帮点一个star


如果是刚接触security的小伙伴,可以先看下这两篇基础博客

security认证过程:

《Spring Security认证过程》

security授权过程:

《Spring Security授权过程》

JWT全面解读、详细使用步骤:

JWT全面解读、详细使用步骤


重要

本文设计和代码是基于 以下博客(请点击)

SpringSecurity 实战项目(一)

SpringSecurity 实战项目(二)

SpringSecurity 实战项目(三)——动态管理Restful风格权限+JWT

进行修改。


一、分析

  1. redis称为缓存数据库主要作用之一就是减少数据库读压力,所以我们要在项目中操作数据库的地方用redis,在这个项目中在登录的时候,查询用户信息并获取用户信息,接着获取用户权限,这两个地方需要去数据库查数据,我们可以在这两个地方加上redis,当用户登录的时候,先去redis查看有没有该用户的信息,如果有就用redis里边的数据进行登录,如果没有则进行进行登录流程,最后把用户数据存入redis里边,下次登录的时候就可以走redis
  2. 我们项目中登录之后会生成一个Token,我们就把这个Token存入redis里边,这个Token里边有用户名,密码,权限,所以我们要在项目中处理这个TokenTokenjson格式的,要从json转换成实体对象,然后交给security进行验证,转换的过程看似简单,实际做起来会发现有一些坑,太过细节的东西我这里就不说了,有兴趣的小伙伴可以自己去试一下。
  3. 上面第二点已经用redis解决了身份认证的问题,下面就是鉴权了,我这个项目是用户携带Token去访问资源,所以我想了一下,目前来说鉴权还用不到redis,因为每次都会携带一个Token,可能我往后写单点登录的时候就需要用到redis吧。
  4. 在把redis引进来的时候,我们想要在过滤器里边使用redis,发现redis的连接方法redisServicenull,就是无法注入,就是因为listener >> filter >> servlet >> spring,所以在过滤器阶段,IOC还没有注入,也就无法使用bean,最后博主用比较原始的方法,直接生成一个bean工厂,把bean给初始化了,这方法虽然感觉不太好,但是可行的,如果其他小伙伴有更好的办法可以一起探讨。可以参考:springboot关于拦截器或者过滤器无法注入bean的问题

好了分析完了,接下来就是编码了。


redis依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
            <version>2.0.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session</artifactId>
            <version>1.3.5.RELEASE</version>
        </dependency>

二、 修改

1. 修改CustomUserService

@Service
public class CustomUserService implements UserDetailsService {
    //自定义UserDetailsService 接口

    @Autowired
    UserDao userDao;
    @Autowired
    PermissionDao permissionDao;
    @Autowired
    private RedisService redisService;


    public UserDetails loadUserByUsername(String username) {
   
        JwtUserDto jwtUserDto;

        //这里先去redis查看有没有key,如果有则去获取用户信息,连续调用两次感觉不太好,这里就不优化了
        if(RedisCheckUser(username) !=null){
   
            jwtUserDto=RedisCheckUser(username);
            List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
            Map JwtMap = getPermissUrlandMethod(jwtUserDto);
            for(Object key : JwtMap.keySet()){
   
                Object value = JwtMap.get(key);
                GrantedAuthority grantedAuthority = new UrlGrantedAuthority((String) key,(String)value);
                grantedAuthorities.add(grantedAuthority);
            }
            return new JwtUser(jwtUserDto.getUsername(), jwtUserDto.getPassword(), grantedAuthorities);

        }else{
   
            //如果redis里边没有缓存用户信息,说明可能是第一次登录,所以要去数据库查信息
            JwtUser user;
            user = userDao.findByUserName(username);
            if(user.getId() != null){
   
   
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值