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。
示例源代码:https://github.com/zhangkaitao/shiro-example;
spring中集成shiro的更多相关文章
-
spring中集成shiro进行安全管理
shiro是一款轻量级的安全框架,提供认证.授权.加密和会话管理四个基础功能,除此之外也提供了很好的系统集成方案. 下面将它集成到之前的demo中,在之前spring中使用aop配置事务这篇所附代码的 ...
-
细说shiro之五:在spring框架中集成shiro
官网:https://shiro.apache.org/ 1. 下载在Maven项目中的依赖配置如下: <!-- shiro配置 --> <dependency> <gr ...
-
[原]CAS和Shiro在spring中集成
shiro是权限管理框架,现在已经会利用它如何控制权限.为了能够为多个系统提供统一认证入口,又研究了单点登录框架cas.因为二者都会涉及到对session的管理,所以需要进行集成. Shiro在1.2 ...
-
十一、Spring Boot 集成Shiro和CAS
1.Shiro 是什么?怎么用? 2.Cas 是什么?怎么用? 3.最好有spring基础 首先看一下下面这张图: 第一个流程是单纯使用Shiro的流程. 第二个流程是单纯使用Cas的流程. 第三个图 ...
-
Spring Boot 集成Shiro和CAS
Spring Boot 集成Shiro和CAS 标签: springshirocas 2016-01-17 23:03 35765人阅读 评论(22) 收藏 举报 分类: Spring(42) 版 ...
-
解决Spring Boot集成Shiro,配置类使用Autowired无法注入Bean问题
如题,最近使用spring boot集成shiro,在shiroFilter要使用数据库动态给URL赋权限的时候,发现 @Autowired 注入的bean都是null,无法注入mapper.搜了半天 ...
-
Spring Boot集成Shiro实战
Spring Boot集成Shiro权限验证框架,可参考: https://shiro.apache.org/spring-boot.html 引入依赖 <dependency> < ...
-
在前后端分离的SpringBoot项目中集成Shiro权限框架
参考[1].在前后端分离的SpringBoot项目中集成Shiro权限框架 参考[2]. Springboot + Vue + shiro 实现前后端分离.权限控制 以及跨域的问题也有涉及
-
Spring Boot 中集成 Shiro
https://blog.csdn.net/taojin12/article/details/88343990
随机推荐
-
最长公共子序列(LCS)
简单的DP. f[i][j]表示序列a中前i个中,序列b中前b个中,组成的最长公共子序列的长度. DP方程: if(a[i-1]==b[j-1]) f[i][j]=f[i-1][j-1]+1; el ...
-
对vector等STL标准容器的排序操作
[+] STL提供的Sort 算法 所有sort算法介绍 sort 中的比较函数 sort 的稳定性 全排序 局部排序 nth_element 指定元素排序 partition 和stable_par ...
-
Openfire的web插件开发
概要 Openfire不仅支持普通插件开发,还支持完整的web插件开发,这次就web插件开发做一个小的实例,本文主要讲解如何加入Servlet和Jsp页面,基本插件的开发请参照上一篇文章. 准备 系统 ...
-
PHP访问连接MYSQL数据库
1.连接数据库 使用mysql_connect()函数建立与MySQL数据库的连接 源码:$con=mysql_connect("主机名或IP","用户名&q ...
-
虚拟主机导入MySQL出现Unknown character set: ‘utf8mb4’
http://www.lmlblog.com/14.html 前几天进行网站搬家,MySQL导入数据的时候,出现以下错误(没有定义的编码集utf8mb4): SQL 查询: ; MySQL 返回:文档 ...
-
jmockit 模拟同一个函数多次调用每次返回不同结果
new Expectations(){{ calendarService.getGeneralCalendar((Date)any); returns(null, new AbrahamResult& ...
-
Java多线程--线程及相关的Java API
Java多线程--线程及相关的Java API 线程与进程 进程是线程的容器,程序是指令.数据的组织形式,进程是程序的实体. 一个进程中可以容纳若干个线程,线程是轻量级的进程,是程序执行的最小单位.我 ...
-
oneinstack远程管理数据库
本篇文章主要内容是本地工具连接数据非网页(网站)连接 如果你想使用网页(网站)连接远程数据库,请看下面的官网教程 OneinStack如何配置MySQL远程连接? 为了安全考虑,OneinStack仅 ...
-
linux nginx配置多个网站
1.建立wwwroot(/home/wwwrooot) 另建立一个wwwroot/test/index.html(网站目录) 2.建立vhost文件(/usr/local/nginx/conf/vho ...
-
Maven-pom-configuration
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...