当前位置: 移动技术网 > IT编程>开发语言>Java > 详解spring与shiro集成

详解spring与shiro集成

2019年07月19日  | 移动技术网IT编程  | 我要评论

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集成,希望对大家有所帮助

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网