【Shiro】使用org.crazycake依赖的ShiroConfig

news2024/12/26 10:38:42

前言

整个Shiro专题中,这个部分是最早需要开始看的,主要先了解ShiroConfig都有哪些东西;由于这个项目使用的redis依赖是org.crazycake的shiro-redis,与我后面所用的不同,所以该部分只是简单的梳理了一下。
PS:这里并没有使用到jwt,只是单纯的shiro+redis。

因为之前的理解,全都作为注释写在了代码上,所以该篇的介绍主要都在代码中。整体来说,该部分内容并不难,如果感兴趣的大佬可以自行往下深入了解,如果多少还有点迷糊的小伙伴,消化消化继续往专题往下看😉。

1、Maven依赖

        <!-- Shiro 核心依赖 -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.4.0</version>
        </dependency>
        <!-- Shiro-redis插件 -->
        <dependency>
            <groupId>org.crazycake</groupId>
            <artifactId>shiro-redis</artifactId>
            <version>3.1.0</version>
        </dependency>

2、ShiroConfig

2.1 开启注解支持

	/**
     * 开启Shiro-aop注解支持
     * 使用代理方式所以需要开启代码支持
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }

    /**
     * 开启Shiro注解支持(例如@RequiresRoles()和@RequiresPermissions())
     * shiro的注解需要借助Spring的AOP来实现
     * 【ps:不知道为什么,这里没有加入该段代码,依然可以使用Shiro的注解】
     */
    @Bean
    public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){
        DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator=new DefaultAdvisorAutoProxyCreator();
        advisorAutoProxyCreator.setProxyTargetClass(true);
        return advisorAutoProxyCreator;
    }

2.2 Shiro基础配置shiroFilterFactory

	/**
     * Shiro基础配置
     * 配置一个Shiro的过滤器bean,这个bean将配置Shiro相关的一个规则的拦截
     * 如什么样的请求可以访问,什么样的请求不可以访问等等
     */
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactory(SecurityManager securityManager){
        // 创建Shiro的拦截的拦截器 ,用于拦截我们的用户请求
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        // 与这个一样 shiroFilterFactoryBean.setSecurityManager(securityManager());
        // 设置Shiro的安全管理,设置管理的同时也会指定某个Realm 用来完成我们权限分配
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        //定义一个Map集合,这个Map集合中存放的数据全部都是规则,用于设置通知Shiro什么样的请求可以访问,什么样的请求不可以访问
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
        // 注意过滤器配置顺序不能颠倒,配置过滤:不会被拦截的链接
        filterChainDefinitionMap.put("/static/**", "anon");
        filterChainDefinitionMap.put("/userLogin/**", "anon");
        // 表示所有的请求路径全部都需要被拦截登录,这个必须必须写在Map集合的最后面,这个选项是可选的
        // 如果没有指定/** ,出现某个请求不符合上面的拦截规则Shiro将方行这个请求
        filterChainDefinitionMap.put("/**", "authc");
        // 配置shiro默认登录界面地址,前后端分离中登录界面跳转应由前端路由控制,后台仅返回json数据
        /*
        用于设置一个登录的请求地址,这个地址可以是一个html或jsp的访问路径,也可以是一个控制器的路径
        作用是用于通知Shiro我们可以使用这里路径转向到登录页面,但Shiro判断到我们当前的用户没有登录时就会自动转换到这个路径
        要求用户完成成功
        简单说,访问的用户 没有登录 或者 token过期 就会跳转到setLoginUrl的路径下
         */
        shiroFilterFactoryBean.setLoginUrl("/userLogin/unauth");
        /*
        // 登录成功后转向页面,由于用户的登录后期需要交给Shiro完成,因此就需要通知Shiro登录成功之后返回到那个位置
        shiroFilter.setSuccessUrl("/success");
        // 用于指定没有权限的页面,当用户访问某个功能是如果Shiro判断这个用户没有对应的操作权限,那么Shiro就会将请求
        // 转向到这个位置,用于提示用户没有操作权限
        shiroFilter.setUnauthorizedUrl("/noPermission");
         */
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }

2.3 安全管理器securityManager

    /**
     * 安全管理器
     * 它是Shiro框架的核心,典型的Facade模式,Shiro通过SecurityManager来管理内部组件实例,
     * 并通过它来提供安全管理的各种服务
     */
    @Bean
    public SecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        // 自定义Session管理
        securityManager.setSessionManager(sessionManager());
        // 自定义Cache实现
        securityManager.setCacheManager(cacheManager());
        // 自定义Realm验证,这个Realm是最终用于完成我们的认证和授权操作的具体对象
        securityManager.setRealm(shiroRealm());
        return securityManager;
    }

2.4 配置Session管理器sessionManager

    /**
     * 配置Session管理器
     * web应用中一般是用web容器对session进行管理,
     * session管理器,创建和管理用户session。通过设置这个管理器,shiro可以在任何环境下使用session。
     * 这里session管理器负责管理sessionDAO,sessionDAO负责管理个性化的session数据(例如redis缓存数据)
     * 用到 redisSessionDAO()
     */
    @Bean
    public SessionManager sessionManager() {
        ShiroSessionManager shiroSessionManager = new ShiroSessionManager();
        shiroSessionManager.setSessionDAO(redisSessionDAO());
        return shiroSessionManager;
    }

2.5 配置RedisSessionDAO

    /**
     * 配置RedisSessionDAO
     * 通过SessionDao管理session数据,针对个性化的session数据存储需要使用sessionDao。
     * DAO大家都用过,数据访问对象,用于会话的CRUD,比如我们想把Session保存到数据库,那么可以实现自己的SessionDAO,通过如JDBC写到数据库;
     * 比如想把Session放到Memcached中,可以实现自己的Memcached SessionDAO;另外SessionDAO中可以使用Cache进行缓存,以提高性能;
     * 用到 redisManager()和sessionIdGenerator()
     * 这里的RedisSessionDAO使用的是shiro-redis开源插件
     */
    @Bean
    public RedisSessionDAO redisSessionDAO() {
        RedisSessionDAO redisSessionDAO = new RedisSessionDAO();
        redisSessionDAO.setRedisManager(redisManager());
        redisSessionDAO.setSessionIdGenerator(sessionIdGenerator());
        redisSessionDAO.setKeyPrefix(SESSION_KEY);
        redisSessionDAO.setExpire(timeout);
        return redisSessionDAO;
    }
补充1:sessionIdGenerator()
	/**
     * SessionID生成器
     */
    @Bean
    public ShiroSessionIdGenerator sessionIdGenerator(){
        return new ShiroSessionIdGenerator();
    }

这里小小的介绍一下这个sessionID生成器,它的实现类中主要是调用JavaUuidSessionIdGenerator类中的generateId方法,然后得到 Serializable对象值后与定义的前缀做字符拼接,最后返回使用的sessionId。

public class ShiroSessionIdGenerator implements SessionIdGenerator {
    /**
     * 实现SessionId生成
     */
    @Override
    public Serializable generateId(Session session) {
        Serializable sessionId = new JavaUuidSessionIdGenerator().generateId(session);
        return String.format("login_token_%s", sessionId);
    }

这个generateId方法到底返回什么?点进去看下源码,原来就是个uuid😂
在这里插入图片描述

2.6 配置Redis管理器redisManager

    /**
     * 配置Redis管理器
     * 这里的RedisManager使用的是shiro-redis开源插件
     */
    @Bean
    public RedisManager redisManager() {
        RedisManager redisManager = new RedisManager();
        redisManager.setHost(host);
        redisManager.setPort(port);
        redisManager.setTimeout(timeout);
        // 我的redis没有设置密码
//        redisManager.setPassword(password);
        return redisManager;
    }

2.7 配置Cache管理器cacheManager

	/**
     * 配置Cache管理器
     * 缓存控制器,来管理如用户、角色、权限等的缓存的
     * 用于往Redis存储权限和角色标识
     * 这里的RedisCacheManager使用的是shiro-redis开源插件
     */
    @Bean
    public RedisCacheManager cacheManager() {
        RedisCacheManager redisCacheManager = new RedisCacheManager();
        redisCacheManager.setRedisManager(redisManager());
        redisCacheManager.setKeyPrefix(CACHE_KEY);
        // 配置缓存的话要求放在session里面的实体类必须有个id标识
        redisCacheManager.setPrincipalIdFieldName("userId");
        return redisCacheManager;
    }

2.8 身份验证器Realm

/**
     * 身份验证器
     * 领域,充当了Shiro与应用安全数据间的“桥梁”或者“连接器”。
     * 也就是说,当对用户执行认证(登录)和授权(访问控制)验证时,Shiro会从应用配置的Realm中查找用户及其权限信息
     * 可以有1个或多个Realm,可以认为是安全实体数据源,即用于获取安全实体的;
     * 可以是JDBC实现,也可以是LDAP实现,或者内存实现等等;由用户提供;
     * 注意:Shiro不知道你的用户/权限存储在哪及以何种格式存储;所以我们一般在应用中都需要实现自己的Realm;
     * 相当于数据源,通过realm存取认证、授权相关数据。
     */
    @Bean
    public ShiroRealm shiroRealm() {
        ShiroRealm shiroRealm = new ShiroRealm();
        shiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());
        return shiroRealm;
    }

Realm中主要重写doGetAuthenticationInfo认证和doGetAuthorizationInfo授权两个方法,具体了解可以看【Shiro】SimpleAuthenticationInfo如何验证password和【Shiro】SimpleAuthorizationInfo如何授权这两篇文章。

2.9 凭证匹配器hashedCredentialsMatcher

    /**
     * 数据密码加密主要是防止数据在浏览器访问后台服务器之间进行数据传递时被篡改或被截获,因此应该在前端到后台的过程中
     * 进行加密,而这里的加密方式是将浏览器中获取后台的明码加密和对数据库中的数据进行加密
     * 这就丢失了数据加密的意义 因此不建议在这里进行加密,应该在页面传递时进行加密
     * 注:
     *   建议浏览器传递数据时就加密数据,数据库中存在的数据也是加密数据,必须保证前端传递的数据
     *   和数据主库中存放的数据加密次数以及盐规则都是完全相同的,否则认证失败
     */
    /**
     * 凭证匹配器
     * 将密码校验交给Shiro的SimpleAuthenticationInfo进行处理,在这里做匹配配置
     */
    @Bean
    public HashedCredentialsMatcher hashedCredentialsMatcher() {
        HashedCredentialsMatcher shaCredentialsMatcher = new HashedCredentialsMatcher();
        // 散列算法:这里使用SHA256算法;
        shaCredentialsMatcher.setHashAlgorithmName(SHA256Util.HASH_ALGORITHM_NAME);
        // 散列的次数,比如散列两次,相当于 md5(md5(""));
        shaCredentialsMatcher.setHashIterations(SHA256Util.HASH_ITERATIONS);
        return shaCredentialsMatcher;
    }

补充2:SHA256Util工具类

public class SHA256Util {
    /**  私有构造器 **/
    private SHA256Util(){};
    /**  加密算法 **/
    public final static String HASH_ALGORITHM_NAME = "SHA-256";
    /**  循环次数 **/
    public final static int HASH_ITERATIONS = 15;
    /**  执行加密-采用SHA256和盐值加密 添加用户的时候才用到**/
    public static String sha256(String password, String salt) {
        // 1加密方法 2被加密的字符串 3盐值(符串或数字) 4hash次数
        return new SimpleHash(HASH_ALGORITHM_NAME, password, salt, HASH_ITERATIONS).toString();
    }
}

补充3:SHA256和salt加密在项目中怎么用

1. 生成一个随机的salt值,这个salt值可以是一个字符串或者一个数字。

2. 将用户输入的密码和salt值拼接起来,然后使用SHA256算法对拼接后的字符串进行加密。

3. 将加密后的字符串存储在数据库中,以便以后使用。

4. 当用户再次输入密码时,将用户输入的密码和数据库中存储的salt值拼接起来,
   然后使用SHA256算法对拼接后的字符串进行加密,将加密后的字符串与数据库中存储的加密字符串进行比较,
   如果两者相同,则表示用户输入的密码正确,反之则表示用户输入的密码错误。

3、ShiroConfig总结图

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/601142.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Hadoop高可用集群

HA高可用集群 HA介绍 什么是HA HA: High Availability&#xff0c;高可用集群&#xff0c;指的是集群7*24小时不间断服务。 为什么需要HA 在HDFS中&#xff0c;有NameNode、DataNode和SecondaryNameNode角色的分布&#xff0c;客户端所有的操作都是要与NameNode交互的&#xff…

PG数据库提示: FATAL: sorry, too many clients already

目录 场景&#xff1a; idea启动提示如下错误 翻译&#xff1a; 连接数相关查询&#xff1a; 原因分析&#xff1a; 解决方法&#xff1a; 场景&#xff1a; idea启动提示如下错误 org.postgresql.util.PSQLException: FATAL: sorry, too many clients alreadyat org.pos…

运维小白必学篇之基础篇第四集:vim文本编辑器实验

vim文本编辑器实验 1、创建a.txt文件&#xff0c;并复制到/tmp/file/目录下 2、创建1.txt文件的软链接文件11.txt 3、移动a.txt文件到/mnt目录下并改名为abc.txt 4、创建d1、d2目录&#xff0c;并在d1目录中创建文件a1、a2 5、删除d1目录和d2目录 6、查看/etc/man_db.conf文件的…

DPCNN:深度金字塔 CNN 文本分类网络

DPCNN&#xff08;Deep Pyramid CNN&#xff09;&#xff0c;是2017年腾讯AI-Lab提出的一种用于文本分类的网络&#xff0c;可以称之为"深度金字塔卷积神经网络"。 论文&#xff1a;Deep Pyramid Convolutional Neural Networks for Text Categorization 在之前的博…

运维小白必学篇之基础篇第五集:用户和组实验

用户和组实验 实验者&#xff1a;胡 阳 1、创建u1用户&#xff0c;指定UID为1050&#xff0c;并为该用户设置密码 2、创建u2用户&#xff0c;设置其不能登录操作系统 3、创建u3用户&#xff0c;指定其家目录为/mnt/u3 4、将u1用户改名为s1 5、创建用户u1&#xff0c;指定其UID…

为什么企业都需要一个ERP系统?对公司管理和业务增长都太重要了

什么是ERP系统&#xff1f; ERP&#xff08;Enterprise Resource Planning&#xff0c;企业资源计划&#xff09;系统是一种应用软件&#xff0c;它通过集成管理企业内部系统和外部合作伙伴系统的各种业务过程&#xff0c;来实现企业资源的最优化配置和利用。ERP系统涵盖了企业…

VMware vSphere 8.0 Update 1a 正式版发布 - 企业级工作负载平台

VMware vSphere 8.0 Update 1a 正式版发布 - 企业级工作负载平台 ESXi 8.0 U1 & vCenter Server 8.0 U1 请访问原文链接&#xff1a;https://sysin.org/blog/vmware-vsphere-8-u1/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sy…

基于java SpringBoot和Vue uniapp的校园信息交流小程序

随着信息社会的网络化和计算机科学的广泛普及和迅速普及应用&#xff0c;具有综合智能的我国校园信息教育网络已成为推动中小学科学教育及其实践科学发展的信息技术手段。迅速推进了信息化改革&#xff0c;改善了高校信息交流的网络环境&#xff0c;提高了信息教育平台的管理水…

利用云服务器搭建云盘(搭建自己的在线存储可上传下载可共享)

Docker部署seafile 背景 由于学校最近有一个需求&#xff0c;搭建一个可供老师使用的在线存储&#xff0c;最后我自己就尝试这搭建。这过程中也出现了不少问题&#xff0c;下面我会说明&#xff01;&#xff01;&#xff01; 准备 需要一台云服务器&#xff08;如果你本地有…

chatgpt赋能python:Python写POC:提高网络安全攻防技能的利器

Python写POC&#xff1a;提高网络安全攻防技能的利器 随着信息化进程的发展&#xff0c;计算机网络的应用越来越广泛&#xff0c;网络安全问题也日益突出。针对网络安全问题的POC&#xff08;Proof Of Concept&#xff0c;概念验证代码&#xff09;作为一种低成本的、快速验证…

chatgpt赋能python:Python冒泡排序法详解

Python冒泡排序法详解 介绍 Python是一种高级编程语言&#xff0c;它设计简洁、易于学习&#xff0c;受到越来越多程序员的欢迎。 在Python编程中&#xff0c;排序算法是非常重要的一部分。其中&#xff0c;冒泡排序法是一种纯粹的比较排序算法&#xff0c;它是大多数排序算…

元宇宙应用领域-运动

元宇宙作为互联网的下一个阶段&#xff0c;目前已经发展成为一个多领域的“平行宇宙”&#xff0c;其中就包括体育。从体育的角度来看&#xff0c;元宇宙将是一个集运动、娱乐、社交、生活、学习于一体的“平行宇宙”&#xff0c;可以让人们在元宇宙中进行更好的运动&#xff0…

ChatGPT下的网站建设会收到哪些影响?

近日&#xff0c;微软发布了人工智能语言模型 ChatGPT&#xff0c;该模型可以理解人类的语言并生成响应式文本。与其他自然语言处理模型不同&#xff0c; ChatGPT具有出色的语言理解能力&#xff0c;并能够生成自然、流畅的文本。 ChatGPT不仅能够回答用户问题&#xff0c;还能…

有关计算机科学与技术论文

有关计算机科学与技术论文篇一 《 计算方法在计算机科学与技术专业教学改革与实践 》 摘要&#xff1a;介绍了对计算机科学与技术专业的计算方法课程教学改革进行的尝试和探索&#xff0c;结合该专业提出了计算方法课程教学改革的几个重点及策略&#xff0c;优化了教学内容、…

CUDA编程中的HANDLE_ERROR( )和book.h-2023

最近个人正在学习cuda编程&#xff0c;这个帖子作为一个经验记录。 第一呢&#xff0c;这本书里面很明显面对的是一些有编程基础的同学准备的&#xff0c;因此他很多细节都是跳过&#xff0c;这就给我们一些初学者带来了困扰。 个人读下来&#xff0c;建议这个文章可以作为参…

T5的整体介绍【代码实战】

T5的整体介绍【代码实战】 0、前言1.Header2.summary3 T5 model3.1 forward3.2 预训练任务3.2.1 multi sentence pairs 3.3 完成 tasks 0、前言 本文是对T5预训练模型的一个介绍&#xff0c;以及能够用来做任务测试&#xff0c;完整的代码稍后挂上链接。 1.Header import torc…

地震勘探基础(四)之地震干扰波

地震记录的干扰波 如下图所示&#xff0c;图上有坏道&#xff0c;面波这样的干扰波。 什么是有效波和干扰波&#xff1f; 有效波&#xff08;Signal&#xff09;&#xff1a;可用来解决所提出的地质任务的波。干扰波&#xff08;Noise&#xff09;&#xff1a;所有妨碍辨认…

于Python的分布式多主题网络爬虫的研究与设计

本文旨在研究和设计一种基于Python的分布式多主题网络爬虫&#xff0c;以实现高效、快速、准确地获取互联网上的信息资源。 一、研究背景 随着互联网的快速发展&#xff0c;信息资源的数量和种类不断增加&#xff0c;如何高效地获取和利用这些信息资源成为了一个重要的问题。…

MySQL 恢复误删数据

文章目录 1、查看是否启用 binlog 日志2、查看所有 binlog 日志3、查看正在使用的日志4、查找日志所在文件夹5、log 日志转 sql6、delete 转 insert 恢复误删 MySQL 恢复误删数据&#xff0c;针对 window 和 Linux 均适用&#xff0c;只需要找到对应的 binlog 目录文件&#xf…

【5G PHY】5G SLIV(Start and Length Indicator Value)介绍

博主未授权任何人或组织机构转载博主任何原创文章&#xff0c;感谢各位对原创的支持&#xff01; 博主链接 本人就职于国际知名终端厂商&#xff0c;负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作&#xff0c;目前牵头6G算力网络技术标准研究。 博客…