Shiro学习(12)与Spring集成
Shiro的组件都是JavaBean/POJO式的组件,所以非常容易使用spring进行组件管理,可以非常方便的从ini配置迁移到Spring进行管理,且支持JavaSE应用及Web应用的集成。
在示例之前,需要导入shiro-spring及spring-context依赖,具体请参考pom.xml。
spring-beans.xml配置文件提供了基础组件如DataSource、DAO、Service组件的配置。
JavaSE应用
spring-shiro.xml提供了普通JavaSE独立应用的Spring配置:
- <!-- 缓存管理器 使用Ehcache实现 -->
- <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
- <property name="cacheManagerConfigFile" value="classpath:ehcache.xml"/>
- </bean>
- <!-- 凭证匹配器 -->
- <bean id="credentialsMatcher" class="
- com.github.zhangkaitao.shiro.chapter12.credentials.RetryLimitHashedCredentialsMatcher">
- <constructor-arg ref="cacheManager"/>
- <property name="hashAlgorithmName" value="md5"/>
- <property name="hashIterations" value="2"/>
- <property name="storedCredentialsHexEncoded" value="true"/>
- </bean>
- <!-- Realm实现 -->
- <bean id="userRealm" class="com.github.zhangkaitao.shiro.chapter12.realm.UserRealm">
- <property name="userService" ref="userService"/>
- <property name="credentialsMatcher" ref="credentialsMatcher"/>
- <property name="cachingEnabled" value="true"/>
- <property name="authenticationCachingEnabled" value="true"/>
- <property name="authenticationCacheName" value="authenticationCache"/>
- <property name="authorizationCachingEnabled" value="true"/>
- <property name="authorizationCacheName" value="authorizationCache"/>
- </bean>
- <!-- 会话ID生成器 -->
- <bean id="sessionIdGenerator"
- class="org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator"/>
- <!-- 会话DAO -->
- <bean id="sessionDAO"
- class="org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO">
- <property name="activeSessionsCacheName" value="shiro-activeSessionCache"/>
- <property name="sessionIdGenerator" ref="sessionIdGenerator"/>
- </bean>
- <!-- 会话验证调度器 -->
- <bean id="sessionValidationScheduler"
- class="org.apache.shiro.session.mgt.quartz.QuartzSessionValidationScheduler">
- <property name="sessionValidationInterval" value="1800000"/>
- <property name="sessionManager" ref="sessionManager"/>
- </bean>
- <!-- 会话管理器 -->
- <bean id="sessionManager" class="org.apache.shiro.session.mgt.DefaultSessionManager">
- <property name="globalSessionTimeout" value="1800000"/>
- <property name="deleteInvalidSessions" value="true"/>
- <property name="sessionValidationSchedulerEnabled" value="true"/>
- <property name="sessionValidationScheduler" ref="sessionValidationScheduler"/>
- <property name="sessionDAO" ref="sessionDAO"/>
- </bean>
- <!-- 安全管理器 -->
- <bean id="securityManager" class="org.apache.shiro.mgt.DefaultSecurityManager">
- <property name="realms">
- <list><ref bean="userRealm"/></list>
- </property>
- <property name="sessionManager" ref="sessionManager"/>
- <property name="cacheManager" ref="cacheManager"/>
- </bean>
- <!-- 相当于调用SecurityUtils.setSecurityManager(securityManager) -->
- <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
- <property name="staticMethod"
- value="org.apache.shiro.SecurityUtils.setSecurityManager"/>
- <property name="arguments" ref="securityManager"/>
- </bean>
- <!-- Shiro生命周期处理器-->
- <bean id="lifecycleBeanPostProcessor"
- class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
可以看出,只要把之前的ini配置翻译为此处的spring xml配置方式即可,无须多解释。LifecycleBeanPostProcessor用于在实现了Initializable接口的Shiro bean初始化时调用Initializable接口回调,在实现了Destroyable接口的Shiro bean销毁时调用 Destroyable接口回调。如UserRealm就实现了Initializable,而DefaultSecurityManager实现了Destroyable。具体可以查看它们的继承关系。
测试用例请参考com.github.zhangkaitao.shiro.chapter12.ShiroTest。
Web应用
Web应用和普通JavaSE应用的某些配置是类似的,此处只提供一些不一样的配置,详细配置可以参考spring-shiro-web.xml。
- <!-- 会话Cookie模板 -->
- <bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
- <constructor-arg value="sid"/>
- <property name="httpOnly" value="true"/>
- <property name="maxAge" value="180000"/>
- </bean>
- <!-- 会话管理器 -->
- <bean id="sessionManager"
- class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
- <property name="globalSessionTimeout" value="1800000"/>
- <property name="deleteInvalidSessions" value="true"/>
- <property name="sessionValidationSchedulerEnabled" value="true"/>
- <property name="sessionValidationScheduler" ref="sessionValidationScheduler"/>
- <property name="sessionDAO" ref="sessionDAO"/>
- <property name="sessionIdCookieEnabled" value="true"/>
- <property name="sessionIdCookie" ref="sessionIdCookie"/>
- </bean>
- <!-- 安全管理器 -->
- <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
- <property name="realm" ref="userRealm"/>
- <property name="sessionManager" ref="sessionManager"/>
- <property name="cacheManager" ref="cacheManager"/>
- </bean>
1、sessionIdCookie是用于生产Session ID Cookie的模板;
2、会话管理器使用用于web环境的DefaultWebSessionManager;
3、安全管理器使用用于web环境的DefaultWebSecurityManager。
- <!-- 基于Form表单的身份验证过滤器 -->
- <bean id="formAuthenticationFilter"
- class="org.apache.shiro.web.filter.authc.FormAuthenticationFilter">
- <property name="usernameParam" value="username"/>
- <property name="passwordParam" value="password"/>
- <property name="loginUrl" value="/login.jsp"/>
- </bean>
- <!-- Shiro的Web过滤器 -->
- <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
- <property name="securityManager" ref="securityManager"/>
- <property name="loginUrl" value="/login.jsp"/>
- <property name="unauthorizedUrl" value="/unauthorized.jsp"/>
- <property name="filters">
- <util:map>
- <entry key="authc" value-ref="formAuthenticationFilter"/>
- </util:map>
- </property>
- <property name="filterChainDefinitions">
- <value>
- /index.jsp = anon
- /unauthorized.jsp = anon
- /login.jsp = authc
- /logout = logout
- /** = user
- </value>
- </property>
- </bean>
1、formAuthenticationFilter为基于Form表单的身份验证过滤器;此处可以再添加自己的Filter bean定义;
2、shiroFilter:此处使用ShiroFilterFactoryBean来创建ShiroFilter过滤器;filters属性用于定义自己的过滤器,即ini配置中的[filters]部分;filterChainDefinitions用于声明url和filter的关系,即ini配置中的[urls]部分。
接着需要在web.xml中进行如下配置:
- <context-param>
- <param-name>contextConfigLocation</param-name>
- <param-value>
- classpath:spring-beans.xml,
- classpath:spring-shiro-web.xml
- </param-value>
- </context-param>
- <listener>
- <listener-class>
- org.springframework.web.context.ContextLoaderListener
- </listener-class>
- </listener>
通过ContextLoaderListener加载contextConfigLocation指定的Spring配置文件。
- <filter>
- <filter-name>shiroFilter</filter-name>
- <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
- <init-param>
- <param-name>targetFilterLifecycle</param-name>
- <param-value>true</param-value>
- </init-param>
- </filter>
- <filter-mapping>
- <filter-name>shiroFilter</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
DelegatingFilterProxy会自动到Spring容器中查找名字为shiroFilter的bean并把filter请求交给它处理。
其他配置请参考源代码。
Shiro权限注解
Shiro提供了相应的注解用于权限控制,如果使用这些注解就需要使用AOP的功能来进行判断,如Spring AOP;Shiro提供了Spring AOP集成用于权限注解的解析和验证。
为了测试,此处使用了Spring MVC来测试Shiro注解,当然Shiro注解不仅仅可以在web环境使用,在独立的JavaSE中也是可以用的,此处只是以web为例了。
在spring-mvc.xml配置文件添加Shiro Spring AOP权限注解的支持:
- <aop:config proxy-target-class="true"></aop:config>
- <bean class="
- org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
- <property name="securityManager" ref="securityManager"/>
- </bean>
如上配置用于开启Shiro Spring AOP权限注解的支持;<aop:config proxy-target-class="true">表示代理类。
接着就可以在相应的控制器(AnnotationController)中使用如下方式进行注解:
- @RequiresRoles("admin")
- @RequestMapping("/hello2")
- public String hello2() {
- return "success";
- }
访问hello2方法的前提是当前用户有admin角色。
当验证失败,其会抛出UnauthorizedException异常,此时可以使用Spring的ExceptionHandler(DefaultExceptionHandler)来进行拦截处理:
- @ExceptionHandler({UnauthorizedException.class})
- @ResponseStatus(HttpStatus.UNAUTHORIZED)
- public ModelAndView processUnauthenticatedException(NativeWebRequest request, UnauthorizedException e) {
- ModelAndView mv = new ModelAndView();
- mv.addObject("exception", e);
- mv.setViewName("unauthorized");
- return mv;
- }
如果集成Struts2,需要注意《Shiro+Struts2+Spring3 加上@RequiresPermissions 后@Autowired失效》问题:
http://jinnianshilongnian.iteye.com/blog/1850425
权限注解
- @RequiresAuthentication
表示当前Subject已经通过login进行了身份验证;即Subject. isAuthenticated()返回true。
- @RequiresUser
表示当前Subject已经身份验证或者通过记住我登录的。
- @RequiresGuest
表示当前Subject没有身份验证或通过记住我登录过,即是游客身份。
- @RequiresRoles(value={“admin”, “user”}, logical= Logical.AND)
表示当前Subject需要角色admin和user。
- @RequiresPermissions (value={“user:a”, “user:b”}, logical= Logical.OR)
表示当前Subject需要权限user:a或user:b。
Shiro学习(12)与Spring集成的更多相关文章
- Activiti学习——Activiti与Spring集成
转: Activiti学习——Activiti与Spring集成 与Spring集成 基础准备 目录结构 相关jar包 Activiti的相关jar包 Activiti依赖的相关jar包 Spring ...
- Shiro学习(22)集成验证码
在做用户登录功能时,非常多时候都须要验证码支持,验证码的目的是为了防止机器人模拟真有用户登录而恶意訪问,如暴力破解用户password/恶意评论等. 眼下也有一些验证码比較简单,通过一些OCR工具就能 ...
- Spring第12篇—— Spring对Hibernate的SessionFactory的集成功能
由于Spring和Hibernate处于不同的层次,Spring关心的是业务逻辑之间的组合关系,Spring提供了对他们的强大的管理能力, 而Hibernate完成了OR的映射,使开发人员不用再去关心 ...
- Shiro学习笔记(5)——web集成
Web集成 shiro配置文件shiroini 界面 webxml最关键 Servlet 測试 基于 Basic 的拦截器身份验证 Web集成 大多数情况.web项目都会集成spring.shiro在 ...
- Shiro之身份认证、与spring集成(入门级)
目录 1. Shro的概念 2. Shiro的简单身份认证实现 3. Shiro与spring对身份认证的实现 前言: Shiro 可以非常容易的开发出足够好的应用,其不仅可以用在 JavaSE 环境 ...
- 2017.2.13 开涛shiro教程-第十二章-与Spring集成(二)shiro权限注解
原博客地址:http://jinnianshilongnian.iteye.com/blog/2018398 根据下载的pdf学习. 第十二章-与Spring集成(二)shiro权限注解 shiro注 ...
- 2017.2.13 开涛shiro教程-第十二章-与Spring集成(一)配置文件详解
原博客地址:http://jinnianshilongnian.iteye.com/blog/2018398 根据下载的pdf学习. 第十二章-与Spring集成(一)配置文件详解 1.pom.xml ...
- Activiti工作流学习(三)Activiti工作流与spring集成
一.前言 前面Activiti工作流的学习,说明了Activiti的基本应用,在我们开发中可以根据实际的业务参考Activiti的API去更好的理解以及巩固.我们实际的开发中我们基本上都使用sprin ...
- 细说shiro之五:在spring框架中集成shiro
官网:https://shiro.apache.org/ 1. 下载在Maven项目中的依赖配置如下: <!-- shiro配置 --> <dependency> <gr ...
- Spring集成shiro做登陆认证
一.背景 其实很早的时候,就在项目中有使用到shiro做登陆认证,直到今天才又想起来这茬,自己抽空搭了一个spring+springmvc+mybatis和shiro进行集成的种子项目,当然里面还有很 ...
随机推荐
- eclipse中服务器找不到项目怎么解决
在我们运行项目前,都需要将项目部署到tomcat上,但是有时我们会遇到这种情况:项目明明存在,但是eclipse中tomcat的add and remove找不到项目,无法部署,那么这个问题该如何解决 ...
- Go(二)函数
函数是一等公民 与其他主要编程语言的差异 1.可以有多个返回值 2.所有参数都是值传递 slice.map.channel会有传引用是错觉,如切片背后是数组,是一个数据结构,里面包含了指向对应数组的指 ...
- 调试Spark应用
本文摘自:<Hadoop专家-管理.调优与Spark|YARN|HDFS安全>Sam R. Alapati 一.通过日志聚合访问日志 二.当日志聚合未开启时
- Delphi ini文件结构简介
一.INI文件的结构:; 注释[小节名]关键字=值 INI文件允许有多个小节,每个小节又允许有多个关键字, “=”后面是该关键字的值. 值的类型有三种:字符串.整型数值和布尔值.其中字符串存贮在INI ...
- Javascript 数组 数字 字符串 时间等使用
1.Javascript 数组API 1. //定义数组 2. var pageIds = new Array(); 3. pageIds.push('A'); 5. 数组长度 6. pageIds. ...
- “void * __cdecl operator new(unsigned int)”(??2@YAPAXI@Z) already defined in LIBCMTD.lib(new.obj)
转自VC错误:http://www.vcerror.com/?p=1377 问题描述: 当 C 运行时 (CRT) 库和 Microsoft 基础类 (MFC) 库的链接顺序有误时,可能会出现以下 L ...
- Insmod模块加载过程分析
一.背景 a) 在进行JZ2440的一个小demo开发的时候,使用自己编译的内核(3.4.2)及lcd模块进行加载时,insmod会提示加载失败因为内核版本不匹配(提示当前内核版本为空),并且显示模块 ...
- MacBook Pro 快捷键2
Mac 键盘快捷键 您可以按下组合键来实现通常需要鼠标.触控板或其他输入设备才能完成的操作. 要使用键盘快捷键,请按住一个或多个修饰键,同时按快捷键的最后一个键.例如,要使用快捷键 Command ...
- LINUXE下执行php 定时任务
linux test.php <?php $fn='/home/root.adminssh/boz/logs'; $data=rand(1,9999); $fp=fopen($fn,'wb'); ...
- select change()
$(".learnStageId").change(function(){ var id = $(this).val(); $(".gradeId").find ...