⭐图例结合超硬核讲解shiro⭐(三)

简介: ⭐图例结合超硬核讲解shiro⭐

七、集成Shiro之Shiro标签(.jsp和.ftl)


7.1.JSP的Shiro标签


在JSP中使用Shiro标签比较简单,我们只需要注意用法即可.下面我就把所以Shiro标签放在下面了,各位看官自行查考:

<shiro:guest>
    游客访问 <a href = "login.jsp"></a>
</shiro:guest>
user 标签:用户已经通过认证\记住我 登录后显示响应的内容
<shiro:user>
    欢迎[<shiro:principal/>]登录 <a href = "logout">退出</a>
</shiro:user>
authenticated标签:用户身份验证通过,即 Subjec.login 登录成功 不是记住我登录的
<shiro:authenticted>
    用户[<shiro:principal/>] 已身份验证通过
</shiro:authenticted>
notAuthenticated标签:用户未进行身份验证,即没有调用Subject.login进行登录,包括"记住我"也属于未进行身份验证
<shiro:notAuthenticated>
    未身份验证(包括"记住我")
</shiro:notAuthenticated>
principal 标签:显示用户身份信息,默认调用
Subjec.getPrincipal()获取,即Primary Principal
<shiro:principal property = "username"/>
hasRole标签:如果当前Subject有角色将显示body体内的内容
<shiro:hashRole name = "admin">
    用户[<shiro:principal/>]拥有角色admin
</shiro:hashRole>
hasAnyRoles标签:如果Subject有任意一个角色(或的关系)将显示body体里的内容
<shiro:hasAnyRoles name = "admin,user">
    用户[<shiro:pricipal/>]拥有角色admin 或者 user
</shiro:hasAnyRoles>
lacksRole:如果当前 Subjec没有角色将显示body体内的内容
<shiro:lacksRole name = "admin">
    用户[<shiro:pricipal/>]没有角色admin
</shiro:lacksRole>
hashPermission:如果当前Subject有权限将显示body体内容
<shiro:hashPermission name = "user:create">
    用户[<shiro:pricipal/>] 拥有权限user:create
</shiro:hashPermission>
lacksPermission:如果当前Subject没有权限将显示body体内容
<shiro:lacksPermission name = "org:create">
    用户[<shiro:pricipal/>] 没有权限org:create
</shiro:lacksPermission>


7.2.Freemark的Shiro标签


1.在SpringBoot里面并不是直接支持JSP文件的,然后我就在项目中使用了Freemark,但是Shiro标签并不能直接支持.ftl文件,所以我们需要先引入一个Maven依赖:

<dependency>
    <groupId>net.mingsoft</groupId>
    <artifactId>shiro-freemarker-tags</artifactId>
    <version>0.1</version>
</dependency>


2.然后,我们写一个名为ShiroTagsFreeMarkerCfg配置类来对Freemark使用Shiro标签进行配置.当然了,要确定配置类能被正确注入到Bean中,代码如下所示:

import com.jagregory.shiro.freemarker.ShiroTags;
import freemarker.template.TemplateModelException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
import javax.annotation.PostConstruct;
@Component
public class ShiroTagsFreeMarkerCfg {
    @Autowired
    private FreeMarkerConfigurer freeMarkerConfigurer;
    @PostConstruct
    public void setSharedVariable() throws TemplateModelException {
        freeMarkerConfigurer.getConfiguration().setSharedVariable("shiro", new ShiroTags());
    }
}


3.配置类搞好之后,我们就可以在.ftl文件中使用Shiro的权限标签了,标签格式如下所示:


<@shiro.guest>  
游客访问 <a href = "login.jsp"></a>
</@shiro.guest> 
user 标签:用户已经通过认证\记住我 登录后显示响应的内容
<@shiro.user>  
欢迎[<@shiro.principal/>]登录,<a href="/logout.html">退出</a>  
</@shiro.user>   
 authenticated标签:用户身份验证通过,即 Subjec.login 登录成功 不是记住我登录的
<@shiro.authenticated>  
    用户[<@shiro.principal/>]已身份验证通过  
</@shiro.authenticated>   
notAuthenticated标签:用户未进行身份验证,即没有调用Subject.login进行登录,包括"记住我"也属于未进行身份验证
<@shiro.notAuthenticated>
    当前身份未认证(包括记住我登录的)
</@shiro.notAuthenticated> 
principal 标签:显示用户身份信息,默认调用
Subjec.getPrincipal()获取,即Primary Principal
<@shiro.principal property="username"/>
hasRole标签:如果当前Subject有角色将显示body体内的内容
<@shiro.hasRole name="admin">  
    用户[<@shiro.principal/>]拥有角色admin<br/>  
</@shiro.hasRole> 
hasAnyRoles标签:如果Subject有任意一个角色(或的关系)将显示body体里的内容
<@shiro.hasAnyRoles name="admin,user,member">  
用户[<@shiro.principal/>]拥有角色admin或user或member<br/>  
</@shiro.hasAnyRoles>   
lacksRole:如果当前 Subjec没有角色将显示body体内的内容
<@shiro.lacksRole name="admin">  
用户[<@shiro.principal/>]不拥有admin角色
</@shiro.lacksRole>   
hashPermission:如果当前Subject有权限将显示body体内容
<@shiro.hasPermission name="user:add">  
    用户[<@shiro.principal/>]拥有user:add权限
</@shiro.hasPermission>   
lacksPermission:如果当前Subject没有权限将显示body体内容
<@shiro.lacksPermission name="user:add">  
    用户[<@shiro.principal/>]不拥有user:add权限
</@shiro.lacksPermission> 

八、会话管理


会话管理器管理着应用中所有 Subject 的会话的创建、维护、删除、失效、验证等工作。是Shiro 的核心组件,顶层组件 SecurityManager 直接继承了 SessionManager,且提供了SessionsSecurityManager 实 现 直 接 把 会 话 管 理 委 托 给 相 应 的 SessionManager ,DefaultSecurityManager 及 DefaultWebSecurityManager 默认 SecurityManager 都继承了SessionsSecurityManager。


8.1.会话相关API


①Subject.getSession()获取会话,等价于Subject.getSession(true),即如果当前没有创建session对象会创建一个;Subject.getSession(false),如果当前没有创建session对象则返回null。


②Subject.getSession(true)


③session.getId()获取当前会话的唯一标识。


④session.getHost()获取当前会话的主机地址。


⑤session.getTimeout() & session.setTimeout(毫秒)设置/获取当前Session的过期时间。


⑥session.getStartTimestamp() & session.getLastAccessTime()获取会话的启动时间及最后访问时间;如果是J2SE环境需要自己定期调用session.touch()去更新最后访问时间;如果是Web环境,每次进入ShiroFilter都会自动调用session.touch()来更新最后访问时间。


⑦session.touch() & session.stop()更新会话最后访问时间以及销毁会话;Subject.logout()会自动调用session.stop()。在Web应用中,调用HttpSession.invalidate()也会自动调用session.stop()来销毁shiro的话。


⑧session.setAttribute(key,val) & session.getAttribute(key) & session.removeAttribute(key)设置/获取/删除 会话属性。


8.2.会话监听器(SessionListener接口)


①onStart(Session)


监听会话创建事件


②onStop(Session)


监听会话销毁事件


③onExpiration(Session)


监听会话过期事件


8.3.SessionDao(会话持久化、提供CRUD操作)


800ad448a9934529a4ce79eeb186ccb1.png


①AbstractSessionDAO 提供了 SessionDAO 的基础实现,如生成会话ID等。


②CachingSessionDAO 提供了对开发者透明的会话缓存的功能,需要设置相应的 CacheManager。


③MemorySessionDAO 直接在内存中进行会话维护。


④EnterpriseCacheSessionDAO 提供了缓存功能的会话维护,默认情况下使用 MapCache 实现,内部使用 ConcurrentHashMap 保存缓存的会话。



50f43a764d7b44238b12d5c17ec7dbcd.png


tips:在实际开发中,如果要用到SessionDAO组件,可以自定义类实现自EnterpriseCacheSessionDAO类,为其注入sessionIdGenerator属性,如果用到缓存的话还可以注入一个缓存的名字。最后将这个SesionDAO组件注入给SessionManager(会话管理器),最后将SessionManager配置给SecurityManager。下图是一个完整的配置细节。


8.4.会话验证


①Shiro提供了会话验证调度器,用于定期的验证会话是否已过期,如果过期将停止会话。


②出于性能考虑,一般情况下都是获取会话的同时来验证会话是否过期并停止会话的;但是如果在Web环境中,如果用户不主动退出是不知道会话是否过期的,因此需要定义的检测会话是否过期,Shiro提供了会话验证调度器来定期检查会话是否过期,SessionValidationScheduler 。


③Shrio也提供了使用Quartz会话验证调度器 QuartzSessionValidationScheduler 。


九、缓存


方法一:


在securityManager配置中添加cacheManager配置项,会注入到realm中。

95709b3aaec747b5b7af2ba170e33631.png


方法二:在realm中配置。


realm本身实现了CacheManagerAware接口

public interface CacheManagerAware {
    /**
     * Sets the available CacheManager instance on this component.
     *
     * @param cacheManager the CacheManager instance to set on this component.
     */
    void setCacheManager(CacheManager cacheManager);
}


securityManager不只会帮realm注入cacheManager,还会帮sessionManager注入cacheManager

<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="cacheManager" ref="redisCacheManager" />
        <property name="realm" ref="myRealm" />
        <property name="sessionManager" ref="sessionManager"/>
    </bean>


这样的话,realm和sessionManager就不用再配缓存


9.1. 集中式缓存


基于Redis的集中式缓存方案:https://github.com/alexxiyang/shiro-redis


基于Memcached的集中式缓存方案:https://github.com/mythfish/shiro-memcached


基于Ehcache集群模式的存放方案:添加链接描述


9.2. 本地缓存


本地缓存的实现有几种方式


(1)直接存放到JVM堆内存


(2)使用NIO存放在堆外内存,自定义实现或者借助于第三方缓存组件。


不论是采用集中式缓存还是使用本地缓存,shiro的权限数据本身都是直接存放在本地的,不同的是缓存标志的存放位置。采用本地缓存方案是,我们将缓存标志也存放在本地,这样就避免了查询缓存标志的网络请求,能更进一步提升缓存效率。


十、shiro修仙进阶


本篇对于shiro的学习到这就结束了 如果有不全或者不足的地方


说明 网址
shiro视频教程 shiro视频教程
shiro系列博客 shiro系列博客
shiro具体操作 shiro具体操作
shiro官方文档 shiro官方文档
目录
相关文章
|
Java API Maven
Maven创建父子工程详解
在微服务盛行的当下,我们创建的工程基本都是父子工程,我们通过父工程来引入jar,定义统一的版本号等,这样我们在子工程中就可以直接引用后使用了,而不需要去重复的声明版本号等,这样会更方便对整个项目的jar包实现统一化管理,让项目的层次更加清晰。
1436 0
Maven创建父子工程详解
|
网络协议 Shell 网络安全
docker容器网络问题
【10月更文挑战第4天】
1464 2
|
开发者 图形学 开发工具
Unity编辑器神级扩展攻略:从批量操作到定制Inspector界面,手把手教你编写高效开发工具,解锁编辑器隐藏潜能
【8月更文挑战第31天】Unity是一款强大的游戏开发引擎,支持多平台发布与高度可定制的编辑器环境。通过自定义编辑器工具,开发者能显著提升工作效率。本文介绍如何使用C#脚本扩展Unity编辑器功能,包括批量调整游戏对象位置、创建自定义Inspector界面及项目统计窗口等实用工具,并提供具体示例代码。理解并应用这些技巧,可大幅优化开发流程,提高生产力。
1202 1
|
机器学习/深度学习 并行计算 编译器
AVX2指令集简介和代码示例
这篇文章介绍了AVX2指令集,它是Intel在2013年为提高处理器并行计算能力引入的SIMD技术。AVX2增强了整数运算,包括256位操作和位操作,还提供了FMA指令及更多广播和转换功能。与AVX相比,AVX2在图像处理和媒体编码等领域有显著优势。文章通过一个C代码示例展示了如何使用AVX2进行向量加法,并提醒编译时需确保支持AVX2指令集。
|
并行计算 Java 应用服务中间件
JUC并发编程超详细详解篇(一)
JUC并发编程超详细详解篇
2175 1
JUC并发编程超详细详解篇(一)
|
Oracle Java 关系型数据库
windows 下 win11 JDK17安装与环境变量的配置(配置简单详细,包含IJ中java文件如何使用命令运行)
本文介绍了Windows 11中安装JDK 17的步骤,包括从官方网站下载JDK、配置环境变量以及验证安装是否成功。首先,下载JDK 17的安装文件,如果没有Oracle账户,可以直接解压缩文件到指定目录。接着,配置系统环境变量,新建`JAVA_HOME`变量指向JDK安装路径,并在`Path`变量中添加。然后,通过命令行(cmd)验证安装,分别输入`java -version`和`javac -version`检查版本信息。最后,作者分享了如何在任意位置运行Java代码,包括在IntelliJ IDEA(IJ)中创建的Java文件,只需去掉包声明,就可以通过命令行直接运行。
6677 1
|
编解码 网络协议 网络性能优化
RTP/RTCP 协议讲解
RTP/RTCP 协议讲解
2555 0
|
JavaScript 前端开发 数据可视化
TradingView量化交易平台API对接开发部署实现
TradingView量化交易平台API对接开发部署实现
|
存储 Java Maven
Maven jar 包下载失败问题处理【配置Maven国内源】
Maven jar 包下载失败问题处理【配置Maven国内源】
1535 0
|
小程序
微信服务商分账思路剖析、设计流程及源码实现
微信服务商分账思路剖析、设计流程及源码实现
619 0