Shiro 与Spring集成

JAVA herman 1085浏览 0评论
公告:“业余草”微信公众号提供免费CSDN下载服务(只下Java资源),关注业余草微信公众号,添加作者微信:xttblog,发送下载链接帮助你免费下载!
本博客日IP超过1800,PV 2600 左右,急需赞助商。
极客时间所有课程通过我的二维码购买后返现24元微信红包,请加博主新的微信号:xttblog,之前的微信号好友位已满,备注:返现
所有面试题(java、前端、数据库、springboot等)一网打尽,请关注文末小程序
视频教程免费领

现在的框架基本上都会与Spring进行集成,很少有单独使用的。通过本文的案例,让我们学会Shiro与Spring的集成。

Shiro的组件都是JavaBean/POJO式的组件,所以非常容易使用Spring进行组件管理,可以非常方便的从ini配置迁移到Spring进行管理,且支持JavaSE应用及Web应用的集成。
本示例需要导入shiro-spring及spring-context依赖。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.xttblog.shiro11..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请求交给它处理。

本文案例源代码下载链接:http://pan.baidu.com/s/1nuKpwYP 密码:8k7t

业余草公众号

最后,欢迎关注我的个人微信公众号:业余草(yyucao)!可加QQ1群:135430763(2000人群已满),QQ2群:454796847(已满),QQ3群:187424846(已满)。QQ群进群密码:xttblog,想加微信群的朋友,之前的微信号好友已满,请加博主新的微信号:xttblog,备注:“xttblog”,添加博主微信拉你进群。备注错误不会同意好友申请。再次感谢您的关注!后续有精彩内容会第一时间发给您!原创文章投稿请发送至532009913@qq.com邮箱。商务合作可添加助理微信进行沟通!

本文原文出处:业余草: » Shiro 与Spring集成