shiro框架---shiro配置介绍(一)
接上一篇文章shiro框架—通过系统介绍shiro框架中的实现逻辑
项目已分享到GitHub
上,如果需要的可以看下,springboot+shiro项目Git下载地址。
shiro在springboot项目中的配置步骤
1、引入依赖
首先shiro的应用,引入的依赖仅仅只有一个,即下边这个。
<dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-all</artifactId><version>1.3.2</version></dependency>
2、shiro在springboot项目中的位置:
以下是shiro在springboot项目中的位置:
主要的文件有四个ShiroConfig
、RetryLimitHashedCredentialsMatcher
、UserRealm
、MShiroFilterFactoryBean
。在这里 `UserOAuthMatcher
没有用到,其实它跟RetryLimitHashedCredentialsMatcher
是一样的意思,都是实现的同一个shiro的接口,用哪一个都可以,我在下边的链接里就不放进UserOAuthMatcher
了。
3、以上配置文件的主要功能:
(1) shiroConfig
关于shiroConfig
的配置主要内容,其实就是下图的这些:
以下是shiroConfig
文件的全部配置。其他的配置文件都是围绕这个文件展开工作的。
package microservice.fpzj.shiro;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.filter.authc.AnonymousFilter;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.web.filter.DelegatingFilterProxy;
import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import java.util.LinkedHashMap;
import java.util.Map;
@Configuration
public class ShiroConfig {@Beanpublic FilterRegistrationBean filterRegistrationBean() {FilterRegistrationBean filterRegistration = new FilterRegistrationBean();filterRegistration.setFilter(new DelegatingFilterProxy("shiroFilter")); filterRegistration.setEnabled(true);filterRegistration.addUrlPatterns("/*"); //过滤规则,即所有的请求filterRegistration.setDispatcherTypes(DispatcherType.REQUEST);return filterRegistration;}/*** 这个即是上边调用的shiroFilter过滤器,也就是shiro配置的过滤器* @return*/@Bean(name = "shiroFilter")public ShiroFilterFactoryBean shiroFilter(){/***MShiroFilterFactoryBean指向自定义过滤器,自定义过滤器对js/css等忽*略**/ShiroFilterFactoryBean bean = new MShiroFilterFactoryBean(); bean.setSecurityManager(securityManager());bean.setLoginUrl("/login");bean.setUnauthorizedUrl("/unauthor");Map<String, Filter>filters = new LinkedHashMap<>();
// filters.put("perms", urlPermissionsFilter());filters.put("anon", new AnonymousFilter());bean.setFilters(filters);//shiro配置过滤规则少量的话可以用hashMap,数量多了要用LinkedHashMap,保证有序,原因未知Map<String, String> chains = new LinkedHashMap<>();chains.put("/login", "anon");chains.put("/unauthor", "anon");chains.put("/logout", "anon");chains.put("/weblogin", "anon");chains.put("/**", "authc");bean.setFilterChainDefinitionMap(chains);return bean;}/*** @see org.apache.shiro.mgt.SecurityManager* @return*/@Bean(name="securityManager")public DefaultWebSecurityManager securityManager() {DefaultWebSecurityManager manager = new DefaultWebSecurityManager();manager.setRealm(userRealm());//manager.setCacheManager(cacheManager());manager.setSessionManager(defaultWebSessionManager());return manager;}/*** @see DefaultWebSessionManager* @return*/@Bean(name="sessionManager")public DefaultWebSessionManager defaultWebSessionManager() {DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();//sessionManager.setCacheManager(cacheManager());sessionManager.setGlobalSessionTimeout(1800000);sessionManager.setDeleteInvalidSessions(true);sessionManager.setSessionValidationSchedulerEnabled(true);sessionManager.setDeleteInvalidSessions(true);sessionManager.setSessionIdCookie(getSessionIdCookie());return sessionManager;}/*** 给shiro的sessionId默认的JSSESSIONID名字改掉* @return*/@Bean(name="sessionIdCookie")public SimpleCookie getSessionIdCookie(){SimpleCookie simpleCookie = new SimpleCookie("webcookie");/*** HttpOnly标志的引入是为了防止设置了该标志的cookie被JavaScript读取,* 但事实证明设置了这种cookie在某些浏览器中却能被JavaScript覆盖,* 可被攻击者利用来发动session fixation攻击*/simpleCookie.setHttpOnly(true);/*** 设置浏览器cookie过期时间,如果不设置默认为-1,表示关闭浏览器即过期* cookie的单位为秒 比如60*60为1小时*/simpleCookie.setMaxAge(-1);return simpleCookie;}/*** @see UserRealm--->AuthorizingRealm* @return*/@Bean@DependsOn(value="lifecycleBeanPostProcessor")public UserRealm userRealm() {UserRealm userRealm = new UserRealm();userRealm.setCredentialsMatcher(credentialsMatcher());//userRealm.setCacheManager(cacheManager());return userRealm;}@Bean(name="credentialsMatcher")public CredentialsMatcher credentialsMatcher() {return new RetryLimitHashedCredentialsMatcher();}/*@Beanpublic EhCacheManager cacheManager() {EhCacheManager cacheManager = new EhCacheManager();cacheManager.setCacheManagerConfigFile("classpath:ehcache.xml");return cacheManager;}*/@Beanpublic LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {return new LifecycleBeanPostProcessor();}
}
下边针对于shiroConfig
文件中的配置,一一说明。
首先该文件的第一个配置为FilterRegistrationBean
。 springboot注入过滤器有多种方式,一种是最简单的@WebFilter注解,一种就是下边的这种,写一个FilterRegistrationBean,然后将自定义过滤器set进去,下边是通过DelegatingFilterProxy
代理的方式,注入容器中名字为shiroFilter
的过滤器,最后设置过滤器的规则。
@Beanpublic FilterRegistrationBean filterRegistrationBean() {FilterRegistrationBean filterRegistration = new FilterRegistrationBean();/***DelegatingFilterProxy做的事情是代理Filter的方法,从application*context里获得bean,从下边可以理解到,它是将容器中名字为shiroFilter*的过滤器加入到过滤器注册bean中**/filterRegistration.setFilter(new DelegatingFilterProxy("shiroFilter")); filterRegistration.setEnabled(true);filterRegistration.addUrlPatterns("/*"); //过滤规则,即所有的请求filterRegistration.setDispatcherTypes(DispatcherType.REQUEST);return filterRegistration;}
既然上边注入的是名字为shiroFilter
的过滤器,那下边就是shiroFilter
的配置
/*** 这个即是上边调用的shiroFilter过滤器,也就是shiro配置的过滤器* @return*/@Bean(name = "shiroFilter")public ShiroFilterFactoryBean shiroFilter(){/***MShiroFilterFactoryBean指向自定义过滤器,自定义过滤器对js/css等忽*略**/ShiroFilterFactoryBean bean = new MShiroFilterFactoryBean(); bean.setSecurityManager(securityManager());bean.setLoginUrl("/login");bean.setUnauthorizedUrl("/unauthor");Map<String, Filter>filters = new LinkedHashMap<>();
// filters.put("perms", urlPermissionsFilter());/*** shiro自己的过滤器,anon,表示不拦截的路径,authc,表示拦截的路径**/filters.put("anon", new AnonymousFilter());bean.setFilters(filters);/**shiro配置过滤规则少量的话可以用hashMap,数量多了要用*LinkedHashMap,保证有序,原因未知。*,anon,表示不拦截的路径,authc,表示拦截的路径。匹配时,首先匹配*anon的,然后最后匹配authc**/Map<String, String> chains = new LinkedHashMap<>();chains.put("/login", "anon");chains.put("/unauthor", "anon");chains.put("/logout", "anon");chains.put("/weblogin", "anon");chains.put("/**", "authc"); bean.setFilterChainDefinitionMap(chains);return bean;}
以上的shiroFilter
配置中,又引入了我们的第二个配置文件,名字为MShiroFilterFactoryBean
,该类继承了ShiroFilterFactoryBean
类,通过名字,应该大体能知道,它是shiro的过滤器工厂类,而我们的MShiroFilterFactoryBean
类就是一个自定义的shiro过滤器,为什么要自己写一个过滤器呢?
在当前的shiro框架中,无法拦截那种.js
、.css
、.html
、.jsp
等等带有.
的请求路径,对于前三种这种静态资源,我们可以不纳入shiro拦截,即可以在不登录的情况下访问成功,但是我们现在有这样的需求,即对.jsp
也要拦截起来,那就需要自定义shiro过滤器了,即现在MShiroFilterFactoryBean
类存在的意义。关于该类的解释,在后边再说,我们继续shiroConfig
文件的介绍。
在上边的配置中,其实就是自定义了一个shiro过滤器,然后对其进行了一些操作,其中bean.setLoginUrl("/login")
是在项目启动后,如果没有登录的情况下,会被shiro强制请求的路径,即为/login
;
另外,bean.setSecurityManager(securityManager());
这句的配置,即引入设置shiro的控制中心,即securityManager
,安全管理器;即所有与安全有关的操作都会与securityManager
交互;且它管理着所有Subject
;可以看出它是Shiro的核心,它负责与后边介绍的其他组件进行交互,如果学习过SpringMVC,你可以把它看成DispatcherServlet前端控制器;关于subject
,你就理解为是每一个访问系统的用户对象即可,所有的访问用户的情况都是一种subject
的体现,它们又统一被securityManager
管理,这个在第一篇里已经说过。
通过上边的shiroFilter
的配置之后,然后再看securityManager
。
/*** @see org.apache.shiro.mgt.SecurityManager* @return*/@Bean(name="securityManager")public DefaultWebSecurityManager securityManager() {DefaultWebSecurityManager manager = new DefaultWebSecurityManager();manager.setRealm(userRealm());//manager.setCacheManager(cacheManager());manager.setSessionManager(defaultWebSessionManager());return manager;}
以上又引入了我们的第三个配置文件,即UserRealm
文件,改文件又引出了我们的一个概念,Realm
:域,Shiro从从Realm获取安全数据(如用户、角色、权限),就是说SecurityManager要验证用户身份,那么它需要从Realm获取相应的用户进行比较以确定用户身份是否合法;也需要从Realm得到用户相应的角色/权限进行验证用户是否能进行操作;可以把Realm看成DataSource,即安全数据源。
在这里的UserRealm
类继承于AuthorizingRealm
,该类的作用其实有用户密码验证、权限授权等。这个也会在后边贴出来,先继续讲shiroConfig
文件。
通过上边的manager.setSessionManager(defaultWebSessionManager());
然后引入下边的配置
/*** @see DefaultWebSessionManager* @return*/@Bean(name="sessionManager")public DefaultWebSessionManager defaultWebSessionManager() {DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();//sessionManager.setCacheManager(cacheManager());sessionManager.setGlobalSessionTimeout(1800000);sessionManager.setDeleteInvalidSessions(true);sessionManager.setSessionValidationSchedulerEnabled(true);sessionManager.setDeleteInvalidSessions(true);sessionManager.setSessionIdCookie(getSessionIdCookie());return sessionManager;}
上边的配置,主要是对session
的配置,比如,超时时间的设置等,基本上都是跟session
相关的配置。另外,上边还有getSessionIdCookie()
方法的引用,众所周知,浏览器与后台系统交互的方式,是以后台存储session
,然后将该session
对应key,以字符串的形式返给浏览器,并在浏览器中以cookie
的形式记录起来,方便后续的访问,如果浏览器丢失了这个cookie
,那就会失去与后台系统的联系,必须重新登录,才能重新再生成这个cookie
。而getSessionIdCookie()
方法,即是对cookie在浏览器那里的名字的定义,如下:
/*** 给shiro的sessionId默认的JSSESSIONID名字改掉* @return*/@Bean(name="sessionIdCookie")public SimpleCookie getSessionIdCookie(){SimpleCookie simpleCookie = new SimpleCookie("webcookie");/*** HttpOnly标志的引入是为了防止设置了该标志的cookie被JavaScript读取,* 但事实证明设置了这种cookie在某些浏览器中却能被JavaScript覆盖,* 可被攻击者利用来发动session fixation攻击*/simpleCookie.setHttpOnly(true);/*** 设置浏览器cookie过期时间,如果不设置默认为-1,表示关闭浏览器即过期* cookie的单位为秒 比如60*60为1小时*/simpleCookie.setMaxAge(-1);return simpleCookie;}
以上配置起的名字为webcookie
,这个webcookie
就是浏览器那边存储后台传入过来的cookie
的key。整个的大体流程,我理解的如下:
以后再请求,只要浏览器没有清除cookie
,上边关于session
的超时时间没有超时,就可以正常访问系统。之所以,这里要给sessionid
起一个名字webcookie
这是防止浏览器访问多个系统的时候,恰巧碰上两个系统在浏览器那边存储sessionid
对应的key正好相同,即session污染
,造成访问系统出现问题。如果不设置,shiro默认的sessionid
在前端浏览器的名字为cookie
。
关于session污染
的异常,我遇到的是下边这个:
Found 'sid' cookie value [1a22b751-0542-4e74-a8e7-59942692f6ae]
22:13:37 DEBUG net.sf.ehcache.Cache - mx-master-SessionCache cache - Miss
22:13:37 DEBUG o.a.shiro.mgt.DefaultSecurityManager - Resolved SubjectContext context session is invalid. Ignoring and creating an anonymous (session-less) Subject instance.
org.apache.shiro.session.UnknownSessionException: There is no session with id [1a22b751-0542-4e74-a8e7-59942692f6ae]
如果出现There is no session with id
的异常,不出意外的话,就是上边的配置有问题,需要有cookie
的配置,相关的文章,你可以看这一篇一个项目两个web模块会导致shiro的session污染 ,可以得到解释。
继续shiroconfig
文件的配置,然后再后边就是如下配置:
@Bean@DependsOn(value="lifecycleBeanPostProcessor")public UserRealm userRealm() {UserRealm userRealm = new UserRealm();userRealm.setCredentialsMatcher(credentialsMatcher());//userRealm.setCacheManager(cacheManager());return userRealm;}@Bean(name="credentialsMatcher")public CredentialsMatcher credentialsMatcher() {return new RetryLimitHashedCredentialsMatcher();}@Beanpublic LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {return new LifecycleBeanPostProcessor();}
上边有userRealm
类的注入,而在前边securityManager
的配置的时候,它引入了userRealm
,就是在这里对userRealm
类注入的。
另外,上边userRealm
方法中设置了一个credentialsMatcher()
,该方法对应的就是new RetryLimitHashedCredentialsMatcher()
类,这里就引入了我们第四个配置文件RetryLimitHashedCredentialsMatcher
类,该类,继承于HashedCredentialsMatcher
类,而HashedCredentialsMatcher
你如果往上找,其实就是实现了CredentialsMatcher
接口,所以这里注入的时候,可以以自定义的RetryLimitHashedCredentialsMatcher
类注入成CredentialsMatcher
,该类的功能主要是将用户输入的密码与查询到的密码进行比较,也就是密码比较器。
这个shiroConfig
类写的有点多,我理解的也有点不足,有些片面,如果有不对的地方,请读者帮我指正,我及时改过来。
另外提到的另外三个配置文件,先不写了,放到下一篇吧,今天写的有点多了。先贴上shiro的这四个配置文件的下载地址shiro的配置
下一篇文章shiro框架—shiro配置介绍(二)
shiro框架---shiro配置介绍(一)相关推荐
- Shiro框架使用及配置之权限管理系统(1)
Shiro框架使用及配置 提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 Shiro框架使用及配置 前言 一.权限管理系统 1.简介: 2.Shrio框架 二.相关配置文件 ...
- Spring集成Shiro框架实战
文章目录 一:什么是Shiro框架 二:Shiro框架简介 1.Shiro基础功能点介绍 2.Shiro的工作原理 3.Shiro的内部工作结构 4.Shiro的身份认证流程 三:Spring集成Sh ...
- Shiro框架在项目中的应用
1.Shiro 框架简介 Shiro 概述 Shiro 是Apache公司推出一个权限管理框架,其内部封装了项目中认证,授权,加密,会话等逻辑操作,通过Shiro框架可以简化我们项目权限控制逻辑的代码 ...
- 用户登录的详细流程(三)Shiro框架
用户登录的详细流程(三)Shiro框架 Shiro框架是一个功能强大的java安全框架,执行身份验证,授权,加密和会话处理. ** 1.核心架构 Authentication (认证):用户身份认证- ...
- shiro框架多realm登录认证配置
我们做shiro框架经常会遇到这种情况,用户数量很多,又不在同一个表里,比如管理员一个表,用户一个表,商家一个表.这时我们就需要用到多realm来配置让他们用不同得realm来进行登录 首先来说思路, ...
- Java 程序员如何使用 Shiro 框架
点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者:冷豪 来自:www.cnblogs.com/learnhow ...
- Spring+Shiro+CAS整合配置笔记
一.前言 Apache Shiro与Spring Security一样是Java的一个安全框架.那为什么与Spring整合却用Shiro?不要问为什么,任性!开个玩笑:D 其实我个人是认为Spring ...
- 一个jsp能取到父类jsp的值吗_「Javaweb」ssm整合权限控制框架shiro,你知道怎么做吗?...
为美好而努力--羊羽科技说. 最近在开发自己的网站,需要权限控制功能,在网上找了一下,找到了我接下来要介绍的shiro框架. shiro框架是Apache公司维护的开源产品之一,其官网对其的简介是这样 ...
- ehcache使用_Java 程序员如何使用 Shiro 框架
Java 程序员如何使用 Shiro 框架 一.架构 要学习如何使用Shiro必须先从它的架构谈起,作为一款安全框架Shiro的设计相当精妙.Shiro的应用不依赖任何容器,它也可以在JavaSE下使 ...
最新文章
- mysql建立pdm模型_如何使用PowerDesigner创建物理数据模型(PDM)
- 2016年第2本:选择的悖论
- linux 服务器 重新启动 慢,Linux系统启动缓慢解决方法[阮胜昌]
- Java文件类字符串getAbsolutePath()方法(带示例)
- Codeforces Round #198 (Div. 1) B,C 动态规划
- flask(四)jinja2模板
- SSH 协议端口号 22 背后的故事
- 【Git】从本地上传到github的文章显示图片的方法
- 关于ADL的查找顺序
- 医疗信息管理系统数据库--MySQL
- MIUI v5内测版泄漏!
- python批量裁剪图片_python批量剪切图片实现代码
- 简要介绍下tensorflow的计算图
- 高分一号数据处理(一):数据下载
- 你有花生我有酒,一本学道看一天(一)
- 我所关心的POS打印机技术参数
- 憨批豪的java成长日记-MYSQL数据库
- 我的世界mod开发(5)做一把无敌的剑
- Sentinel流量防卫兵
- vscode配置C/C++环境(超详细保姆级教学)
热门文章
- JAVA生成阿里云直播推流和拉流
- 计算机趣事 英语作文,寒假趣事英语作文(通用10篇)
- javascript+css实现走马灯图片轮播器
- 基于WFP的windows驱动对TCP数据的抓取,修改以及注意事项
- 【叶子函数分享五十四】汉字转拼音函数
- 天翼云混合云容灾技术解析
- excel取消保存微软_如何使用Microsoft的“ Excel中的资金”功能管理您的个人财务...
- Checking Table 设计模式 - 从概念、建模、设计到实现——兼谈基于业务需求驱动的设计模式创新
- Nginx开启GZIP压缩,提升前端访问速度
- qq邮箱收信服务器imap,普通IMAP、POP邮箱的设置 教你使用iPhone邮件客户端管理QQ邮箱...