分享

shiro安全框架扩展教程--如何自定义适合项目的过滤器

 WindySky 2018-02-09

        上一章节我给大家讲了如何设计扩展动态修改shiro的资源而不用重启项目,这个章节我讲的是如何自定义我们的特殊过滤器


讲到认证这一块,我们经常用到就是authc,roles,perms这三个标签,说到底标签其实就是一个map的key,然后指向filter实例,相信大家都懂这个了,所以我就不啰嗦,下面我们看看roles的filter实现类


  1. package org.apache.shiro.web.filter.authz;  
  2.   
  3. import java.io.IOException;  
  4. import javax.servlet.ServletRequest;  
  5. import javax.servlet.ServletResponse;  
  6. import org.apache.shiro.subject.Subject;  
  7. import org.apache.shiro.util.CollectionUtils;  
  8.   
  9. // Referenced classes of package org.apache.shiro.web.filter.authz:  
  10. //            AuthorizationFilter  
  11.   
  12. public class RolesAuthorizationFilter extends AuthorizationFilter  
  13. {  
  14.   
  15.     public RolesAuthorizationFilter()  
  16.     {  
  17.     }  
  18.   
  19.     public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue)  
  20.         throws IOException  
  21.     {  
  22.         Subject subject = getSubject(request, response);  
  23.         String rolesArray[] = (String[])(String[])mappedValue;  
  24.         if(rolesArray == null || rolesArray.length == 0)  
  25.         {  
  26.             return true;  
  27.         } else  
  28.         {  
  29.             java.util.Set roles = CollectionUtils.asSet(rolesArray);  
  30.             return subject.hasAllRoles(roles);  
  31.         }  
  32.     }  
  33. }  

我们可以看到其实这个roles的filter是通过subject.hasAllRoles(roles)判断是否满足所有权限,但是我们真实项目中,很多时候用户只要满足其中一个角色即可认为是授权认证成功,所以这个时候,我们首先想到的是再写个filter吧,那我们下面就写个满足任一角色即可放行的授权认证类


  1. public class RoleAuthorizationFilter extends AuthorizationFilter {  
  2.   
  3.     public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue)  
  4.             throws IOException {  
  5.   
  6.         Subject subject = getSubject(request, response);  
  7.         String[] rolesArray = (String[]) mappedValue;  
  8.   
  9.         if (rolesArray == null || rolesArray.length == 0) {  
  10.             // no roles specified, so nothing to check - allow access.  
  11.             return true;  
  12.         }  
  13.   
  14.         Set<String> roles = CollectionUtils.asSet(rolesArray);  
  15.         for (String role : roles) {  
  16.             if (subject.hasRole(role)) {  
  17.                 return true;  
  18.             }  
  19.         }  
  20.         return false;  
  21.     }  
  22.   
  23. }  


很简单的样子,其实就是从RolesAuthorizationFilter这个类copy一份代码过来,然后把subject.hasAllRoles()换成遍历调用subject.hasRole()方法,如存在任一角色则返回true即可


最后我们把这个filter要配置到主过滤器里,并且定义标签为role


  1. <!-- 过滤链配置 -->  
  2.     <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">  
  3.         <property name="securityManager" ref="securityManager" />  
  4.         <property name="loginUrl" value="/" />  
  5.         <property name="successUrl" value="/cms/index.do" />  
  6.         <property name="unauthorizedUrl" value="/" />  
  7.         <property name="filters">  
  8.             <map>  
  9.                 <entry key="role">  
  10.                     <bean  
  11.                         class="com.silvery.security.shiro.filter.RoleAuthorizationFilter" />  
  12.                 </entry>  
  13.                 <entry key="authc">  
  14.                     <bean  
  15.                         class="com.silvery.security.shiro.filter.SimpleFormAuthenticationFilter" />  
  16.                 </entry>  
  17.             </map>  
  18.         </property>  
  19.     </bean>  

象上述配置就是使用自定义过滤器,如: /test/** = role[admin]  或者  /test/** = role[admin,user] 这样用户拥有任一定义的角色都能认证成功

由上述的自定义filter可以看出,我们在shiro上增加其他filter并不难,所以如果需要增加其他filter就不需要担心实现不了...



    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多