深入浅出 Spring Boot 与 Shiro:构建安全认证与权限管理框架

news/2024/11/6 22:47:44/

一、Shiro框架概念

(一)Shiro框架概念

1.概念:

  • Shiro是apache旗下一个开源安全框架,它对软件系统中的安全认证相关功能进行了封装,实现了用户身份认证,权限授权、加密、会话管理等功能,组成一个通用的安全认证框架。
  • 工作流程如下图所示:

2.Shiro框架的三大组件:

  • Subject:主体对象,用于提交用户认证和授权作息。
  • SecurityManager:安全管理器,负责认证、授权等业务实现。(程序员需要配置该类)
  • Realm:领域对象,负责从数据层获取业务数据。(需要程序员提供Shiro框架定义的抽象类AuthorizingRealm(授权Realm)或AuthenticatingRealm(认证Realm)。
  • 三大组件工作流程

3.Shiro框架的相关组件具体作用:

  • Shiro框架进行权限管理时,涉及了一些核心对象,主要包括:认证管理对象,授权管理对象,会话管理对象,缓存管理对象,加密管理对象以及Realm管理对象等。
    • 具体架构如图所示:

  • 核心对象具体作用:
  • Subject:与软件交互的一个特定的实体(用户、第三方服务等)。
  • SecurityManager:Shiro的核心,用来协调管理组件工作。
  • Authenticator:负责认证操作。
  • Authorizer:负责授权检测。
  • SessionManager(会话管理):负责创建并管理用户Session生命周期。
  • SessionDao:代表SessionManager执行Session持久(CRUD)操作,它允许任何存储的数据挂接到Session管理基础上。
  • CacheManager:提供创建缓存实例和管理缓存生命周期的功能。
  • Cryptography(加密管理器):提供了加密方式的设计及管理。
  • Realm(领域对象):是Shiro和应用程序安全数据的桥梁。

二、SpringBoot整合Shiro

(一)所需依赖

<dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring-boot-web-starter</artifactId><version>1.7.1</version>
</dependency>

1.当添加该依赖后需要对项目进行初始化否则项目会启动失败。

原因:添加该依赖启动项目时,Shiro框架会要求创建一个Realm对象并交给Spring框架管理。

(二)完成Shiro配置

1.在application.yml/application.properties文件中

shiro:loginUrl: /login

(三)完成Shiro框架整合

  • 提供Realm的实现类:
    • Realm定义与实现结构及提供Realm实现类的方式

  • 具体实现过程:
    • 提供Realm的具体实现类SysShiroRealm.
      • 将SysShiroRealm对象交给Spring管理。如下图:

    三、通过Shiro框架认证实现

    (一)配置认证过滤链

    1.实现方法:

    • 配置一个ShiroFilterChainDefinition的实现类DefaultShiroFilterChainDefinition对象,在该对象中配置具体过滤链。完成配置后将该对象交于Spring管理。

    2.具体实现:

    @Bean
    public ShiroFilterChainDefinition shiroFilterChainDefinition()
    {DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition();chainDefinition.addPathDefinition("/login", "anon");chainDefinition.addPathDefinition("/assets/**", "anon");chainDefinition.addPathDefinition("/forgetpw", "anon");chainDefinition.addPathDefinition("/user/logininfo", "anon");chainDefinition.addPathDefinition("/logout", "logout");/*chainDefinition.addPathDefinition("/**", "authc");*/return chainDefinition;
    }
    • 细节如下图所示

    (二)提交用户登录信息给Shiro框架的securityMananger。

    实现方法:通过Subject对象调用login()方法实现。

    第一步:从前端获取用户信息通过Ajax或Axios提交给controller

    第二步:controller获取前端提供的用户登录信息,并封装成UsernamePasswordToken做为参数传递给Subject对象。Subject对象调用login方法将用户登录信息提交给SecurityManager进行登录校验。具体如下图:

    (三)数据库获取用户认证信息交给Shiro框架的SecurityManager。

    实现方法:通过重写doGetAuthenricatingInfo()实现

    第一步:向SecurtiyManager提供用户凭证加密方式:

    • 原因:
      • 由于通过Subject的login方法传给SecurityManager的用户的密码为明文密码,而数据库中保存的是加密盐和加密密码,因此需要提供加密方法,供SecurityManager调用对明文密码进行加密操作完成与加密后的密码校验。
    • 方法:
      • 提供加密方法需要重写AuthorizingReaml的方法getCredentialsMatcher方法,该方法返回一个CredentialsMatcher(凭证匹配器)的实现类HashedCredentialsMatcher(针对MD5加密)的对象。
    • 具体实现:

    第二步:重写认证方法doGetAuthenticatingInfo方法,返回一个AuthenticationInfo的实现类SimpleAuthenticationInfo对象。用于封装数据库中用户凭证信息。

    • 目的:封装从数据库获取的用户凭证信息,用于SecurityManager认证操作。
    • 具体实现:
        • 其中:SimpleAuthenticationInfo对象的构造方法:如图所示。

    (四)完成认证

    • 由SecurityManager内部完成,无需程序员干预。

    (五)对认证结果进行处理。

    1.SecurityMananger认证结果:

    • 用户不存在:SecurityManager抛出UnknowAccountException。
    • 密码不匹配:SecurityManager抛出IncorrectCredetialsException。
    • 账号锁定:SecurityManager抛出LockedAccountException。

    2.通过全局异常处理类完成认证结果信息普通化:

    (六)获取用户登陆信息

    1.方法:

    • 通过shiro框架的subject组件获取。

    2.具体实现:

    • SysUsersPojo usersPojo = (SysUsersPojo) SecurityUtils.getSubject().getPrincipal();

    四、通过Shiro框架实现授权

    (一)实现授权的方式

    • Shiro框架实现授权是通过AOP的方式实现的。
      • 底层通过@annontation切入点表达式来定义切点。
        • 自定义的Annontation为@RequiresPremissions。
        • 注解实参:自定义的授权标识标识。
          • 作用:用于标识访问该方法需要的权限。
        • 目标方法是需要授权才能访问的方法。
        • 具体使用方法:

    (二)授权的前置依赖

    • 由于Shiro框架的授权是通过AOP来实现的,因此,要实现Shiro授权,就必须在项目中添加SpringAop依赖。
    • 即:
      • <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

    (三)授权实现流程

    1.认证是授权的基础。

    2.实现流程

    • 当用户访问需要授权的资源时,SecurityManager调用Realm中的doGetAuthorizationInfo()方法。
    • 该方法从用户认证信息中获取用户信息。
    • 通过用户信息获取用户所拥有的所有授权信息,封装成AuthorizationInfo实现类的对象。
    • SecurityManager内部完成授权信息校验。
      • 如果用户拥有该授权标识,则访问该方法;如果用户没有该授权标识,则SecurityManager出抛出AuthorizationEexception,终止访问。

    (四)具体实现过程

    1.使用@RequiresPermissions描述需要授权才能访问的方法。

    2.重写Realm中的doGetAuthorizationInfo方法,用于封装数据库的保存的该用户拥有的所有授权标识以供SecurityManager授权校验时使用。

    3.授权中可能存在的问题

    • 存在问题:当使用@RequiresPermissions注解描述需要授权访问的Controller层方法时,导致该方法无法被访问。
    • 产生原因:
      • Shiro框架实现授权是通过AOP的方式实现。
      • 当@RequiresPermissions描述目标方法时,Shiro会为该方法所在类创建一个CGLIB代理对象。
      • 在创建代理对象时,默认情况下,原Controller方法上的@RequestMapping等类似注解失效。导致无法访问该Controller方法。
    • 解决方法:
      • 解决原理:
        • AOP创建代理对象是通过DefaultAdvisorAutoProxyCreator对象完成的。
      • 解决方法:
        • 修改DefaultAdvisorAutoProxyCreator对象配置,让原对象上注解生效。
      • 具体实现。

    五、认证授权总结

    (一)用户信息流转流程


http://www.ppmy.cn/news/1544898.html

相关文章

基于python主观题自动阅卷系统毕业设计项目

基于python主观题自动阅卷系统毕业设计项目 大家好&#xff0c;我是陈辰学长&#xff0c;一名在 Java 圈辛勤劳作的码农。今日&#xff0c;要和大家分享的是一款基于python主观题自动阅卷系统毕业设计。项目源码以及部署相关事宜&#xff0c;请联系陈辰学长&#xff0c;文末会…

opencv保姆级讲解-guI和pymsql实现人脸识别打卡(6)

PySimpleGUI 库 ​ PySimpleGUI 是一个用于简化 GUI 编程的 Python 包&#xff0c;它封装了多种底层 GUI 框架&#xff08;如 tkinter、Qt、WxPython 等&#xff09;&#xff0c;提供了简单易用的 API。PySimpleGUI 包含了大量的控件&#xff08;也称为小部件或组件&#xff0…

VMware虚拟机-Ubuntu设置共享文件夹

VMware虚拟机-Ubuntu设置共享文件夹&#xff08;超详细&#xff09;_vmware ubuntu共享文件夹-CSDN博客

scala学习记录,Set,Map

set&#xff1a;集合&#xff0c;表示没有重复元素的集合&#xff0c;特点&#xff1a;唯一 语法格式&#xff1a;val 变量名 Set [类型]&#xff08;元素1&#xff0c;元素2...&#xff09; 可变不可变 可变&#xff08;mutable&#xff09;可对元素进行添加&#xff0c;删…

【安当产品应用案例100集】029-使用安全芯片保护设备核心业务逻辑

我国工业企业普遍缺乏数据安全意识&#xff0c;对数据安全保护缺乏基本认识。这导致企业在数据安全方面的投入不足&#xff0c;保护能力基本不具备&#xff0c;难以有效应对数据安全风险。不过随着安全事件越来越多&#xff0c;很多工业企业的安全意识也越来越高&#xff0c;在…

常见的排序算法(二)

归并排序 归并排序&#xff08;Merge Sort&#xff09;是一种基于分治法&#xff08;Divide and Conquer&#xff09;的排序算法。它将一个大的问题分解成小的问题&#xff0c;然后递归地解决这些小问题&#xff0c;最后合并&#xff08;merge&#xff09;得到最终的排序结果。…

ABAP Git PULL 出错:DDIF_TABLE_PUT

我的 SAP NW ABAP 和 BASIS 版本是 Release 750 SP Level 0014。我从 https://github.com/SAP/code-pal-for-abap 下载了 CodePAL 1.16.3 版本的 .zip 文件。当我在 ABAPGit 中创建离线版本库并导入 .zip 文件&#xff0c;然后拉出 .zip 文件时&#xff0c;出现了以下错误。 确…

Linux Qt 6安装Oracle QOCI SQL Driver插件(适用WSL)

本文参考 QOCI for the Oracle Call Interface (OCI)。 除一般的 Linux 系统外&#xff0c;本文也适用于 WSL 2。 在开始之前&#xff0c;如果没有安装 QOCI 插件&#xff0c;则试图链接 Oracle 数据库时会报错&#xff1a; Failed to create wl_display (No such file or dire…