详解spring与shiro集成
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; }
权限注解
@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。
总结
以上所述是小编给大家介绍的详解spring与shiro集成,希望对大家有所帮助
上一篇: Android仿微信朋友圈图片查看器
下一篇: 自定义容器和字体大小