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进行集成的种子项目,当然里面还有很 ...
随机推荐
- 【leetcode】984. String Without AAA or BBB
题目如下: Given two integers A and B, return any string S such that: S has length A + B and contains exa ...
- 那些长短不一的PCI-E插槽都有什么不一样?
https://www.ednchina.com/news/20171121-PCI-E.html 时间:2017-11-21 目前PCI-E插槽已经成为了主板上的主力扩展插槽,除了显卡会用到P ...
- mysql学习-explain中的extra
覆盖索引就是创建的索引和查询的字段正好个数顺序一致 using filesort:mysql使用了一个外部索引 ,而非表内索引顺序进行访问,,mysql无法利用索引完成的排序操作称为文件索引,如果你创 ...
- ASP.NET MVC 分页之 局部视图
using System; using System.Collections.Generic; using System.Linq; using System.Security.Cryptograph ...
- js事件冒泡、事件捕获
事件冒泡 var box = document.querySelector('.box'); var content = document.querySelector('.content'); doc ...
- ansible 远程执行时提示 command not found 问题
问题 最近在学习 ansible ,在使用普通用户远程执行 ip a 命令是发现提示错误:/bin/sh: ip: command not found. 原因 command not found 命令 ...
- sqlserver定时作业,定时执行存储过程
首先,我想说,我真的是渣了,一个这个玩意弄了半天,算了,直接切入正题吧. 第一步: 先写好存储过程 用了两张表,你们自己建立吧 <br data-filtered="filtered& ...
- PAT_A1131#Subway Map
Source: PAT A1131 Subway Map (30 分) Description: In the big cities, the subway systems always look s ...
- upc组队赛6 Odd Gnome【枚举】
Odd Gnome 题目描述 According to the legend of Wizardry and Witchcraft, gnomes live in burrows undergroun ...
- 递归中,调用forEach方法问题
1 function traverse(objNmae,obj,url){ url = url || objNmae; if(typeof obj === "object" ){ ...