前言:本文项目学习自 https://www.bilibili.com/video/BV11e4y1n7BH?p=12,下面为笔记总结
<dependencies>
<dependency>
<groupId>org.apache.shirogroupId>
<artifactId>shiro-spring-boot-web-starterartifactId>
<version>1.9.0version>
dependency>
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plus-boot-starterartifactId>
<version>3.0.5version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.46version>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-thymeleafartifactId>
dependency>
<dependency>
<groupId>com.github.theborakompanionigroupId>
<artifactId>thymeleaf-extras-shiroartifactId>
<version>2.0.0version>
dependency>
<dependency>
<groupId>org.apache.shirogroupId>
<artifactId>shiro-ehcacheartifactId>
<version>1.4.2version>
dependency>
<dependency>
<groupId>commons-iogroupId>
<artifactId>commons-ioartifactId>
<version>2.6version>
dependency>
dependencies>
role 表
role_user 表
user 表
设置 SecurityManager,并装入自定义的 Realm、rememberMe、缓存管理器
缓存管理器的参数配置在了 xml 中
补充:配置多 Realm
配置多 Realm,首先要实现多个 Realm,在配置类中将这些 Realm 注入,并在 SecurityManager 中指定策略、装入这些 Realm 的集合即可
当应用程序配置多个 Realm 时,例如:用户名密码校验、手机号验证码校验等等。
Shiro 的 ModularRealmAuthenticator 会使用内部的 AuthenticationStrategy 组件判断认证是成功还是失败。
AuthenticationStrategy 是一个无状态的组件,它在身份验证尝试中被询问 4 次(这4 次交互所需的任何必要的状态将被作为方法参数):
(1)在所有 Realm 被调用之前
(2)在调用 Realm 的 getAuthenticationInfo 方法之前
(3)在调用 Realm 的 getAuthenticationInfo 方法之后
(4)在所有 Realm 被调用之后
认证策略的另外一项工作就是聚合所有 Realm 的结果信息封装至一个
AuthenticationInfo 实例中,并将此信息返回,以此作为 Subject 的身份信息。
Shiro 中定义了 3 种认证策略的实现,ModularRealmAuthenticator 内置的认证策略默认实现是AtLeastOneSuccessfulStrategy 方式。可以通过配置修改策略
输入完信息后,点击登录
可以看到后端已经来到对应接口
先是来到了我们的登录认证方法 doGetAuthenticationInfo
之后来到了我们自定义的 Realm 的授权方法 doGetAuthorizationInfo
并在授权方法这里获取角色、权限
成功来到了首页
若登录时没有勾选记住我,那么后台也不会走 RememberMe 的逻辑,不会存入 Cookies 中用户信息,我们访问一个需要认证登录的页面,则直接跳转到登录页面
另外如果我们不勾选记住我,那么自然也不会有对应的 Cookies
我们试着勾选记住我
点击登出后,对应的 Cookies 也被清除了
前端页面使用 shiro-thymeleaf 模板,进行角色或权限的个性化功能展示
后台也要做好校验,直接用注解即可
加入 李四 登录,在之前数据表中我们的测试数据是李四没有这些权限,并且是用户角色,因此前端不会显示,后台接口之间访问也会阻止
而张三我们的数据中设定的是他有这两种权限以及admin管理员角色,下面测试便可以展示
在 ShiroConfig 中先注释掉缓存管理器
我们走一条有角色校验的请求,多走几次发现,每走一次后台都会打印 dao 层的日志,可见每次都需要去数据库查一次
接下来我们把之前的注释去掉,开启缓存管理器,我们还是访问上面的请求,发现并不会再查一次数据库,那么缓存便配置成功了
(1)@RequiresAuthentication
验证用户是否登录,等同于方法subject.isAuthenticated()
(2)@RequiresUser
验证用户是否被记忆:
登录认证成功subject.isAuthenticated()为true
登录后被记忆subject.isRemembered()为true
(3)@RequiresGuest
验证是否是一个guest的请求,是否是游客的请求
此时subject.getPrincipal()为null
(4)@RequiresRoles
验证subject是否有相应角色,有角色访问方法,没有则会抛出异常
AuthorizationException。
例如:@RequiresRoles(“aRoleName”)
void someMethod();
只有subject有aRoleName角色才能访问方法someMethod()
(5)@RequiresPermissions
验证subject是否有相应权限,有权限访问方法,没有则会抛出异常
AuthorizationException。
例如:@RequiresPermissions (“file:read”,”wite:aFile.txt”)
void someMethod();
subject必须同时含有file:read和wite:aFile.txt权限才能访问方法someMethod()
会话管理器,负责创建和管理用户的会话(Session)生命周期,它能够在任何环境中在本地管理用户会话,即使没有Web/Servlet/EJB容器,也一样可以保存会话。默认情况下,Shiro会检测当前环境中现有的会话机制(比如Servlet容器)进行适配,如果没有(比如独立应用程序或者非Web环境),它将会使用内置的企业会话管理器来提供相应的会话管理服务,其中还涉及一个名为SessionDAO的对象。SessionDAO负责Session的持久化操作(CRUD),允许Session数据写入到后端持久化数据库
SessionManager由SecurityManager管理。Shiro提供了三种实现
(1) DefaultSessionManager:用于JavaSE环境
(2) ServletContainerSessionManager:用于web环境,直接使用Servlet容器的会话
(3) DefaultWebSessionManager:用于web环境,自己维护会话(不使用Servlet容器的
会话管理)
编码
Session session = SecurityUtils.getSubject().getSession();
session.setAttribute(“key”,”value”)
说明
Controller 中的 request,在 shiro 过滤器中的 doFilerInternal 方法,被包装成
ShiroHttpServletRequest。
SecurityManager 和 SessionManager 会话管理器决定 session 来源于 ServletRequest还是由 Shiro 管理的会话。
无论是通过 request.getSession 或 subject.getSession 获取到 session,操作
session,两者都是等价的。