shiro角色( roles)自定义Filter----同一个URL配置多个角色的或关系



情况介绍


roles:

正常情况下URL路径的拦截设置如下:

/admins/user/**=roles[admin]


参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,当有多个参数时,例如/admins/user/**=roles["admin,guest"]

但是这个设置方法是需要每个参数满足才算通过,相当于hasAllRoles()方法。

也就是我们的角色必须同时拥有admin和guest权限才可以。


我们可以看到其实这个roles的filter是通过subject.hasAllRoles(roles)判断是否满足所有权限,但是我们真实项目中,很多时候用户只要满足其中一个角色即可认为是授权认证成功。


apache shiro 的角色过滤是 and的关系,需要重新写成or的关系。



方法


我们可以通过自定义Filter来实现这个功能。不但是roles方法,athuc等也可以自定义重写。

roles改成或的判断实现方式很简单,实现AuthorizationFilter类就行了。

新建类CustomRolesAuthorizationFilter.java


package com.test.web.support.shiro;
import javax.servlet.ServletRequest;  
import javax.servlet.ServletResponse;  
  
import org.apache.shiro.subject.Subject;  
import org.apache.shiro.web.filter.authz.AuthorizationFilter;  
  
// AuthorizationFilter抽象类事项了javax.servlet.Filter接口,它是个过滤器。  
public class CustomRolesAuthorizationFilter extends AuthorizationFilter {  
  
    @Override  
    protected boolean isAccessAllowed(ServletRequest req, ServletResponse resp, Object mappedValue) throws Exception {  
        Subject subject = getSubject(req, resp);  
        String[] rolesArray = (String[]) mappedValue;  
  
        if (rolesArray == null || rolesArray.length == 0) { //没有角色限制,有权限访问  
            return true;  
        }  
        for (int i = 0; i < rolesArray.length; i++) {  
            if (subject.hasRole(rolesArray[i])) { //若当前用户是rolesArray中的任何一个,则有权限访问  
                return true;  
            }  
        }  
  
        return false;  
    }  
}



修改shiro配置


主要是修改shiroFilter的bean中的 filters。增加一个对应如下:








 
                                            class="com.test.web.support.shiro.CustomRolesAuthorizationFilter" />  
               
 




/**/*.* = anon
/login = anon
/student/** =roles["admin,normal,assistant"]
/teacher/** =roles["admin,normal,assistant"]
/class/** =roles["admin,normal,assistant"]
/grade/** =roles["admin,normal"]
/** = authc





需要注意的是filters中的entry 的key现在是roles,这里需要与filterChainDefinitions中的拦截方法 roles对应。(shiro默认使用的就是roles)。
如果我要改成  /student/** =role["admin,normal,assistant"] 来做拦截则entry 的key也需要修改成role。
entry 的关联bean是com.test.web.support.shiro.CustomRolesAuthorizationFilter,也就是我们新建的CustomRolesAuthorizationFilter.java类,也需要对应起来。



重写多个 在filters的map中并列增加map即可,如下,我又增加一个athuc的验证。







authc
">
class="com.test.web.support.shiro.AjaxCompatibleAuthenticationFilter">

roles">  
                                            class="com.test.web.support.shiro.CustomRolesAuthorizationFilter" />  
               
 




/**/*.* = anon
/login = anon
/student/** =roles["admin,normal,assistant"]
/teacher/** =roles["admin,normal,assistant"]
/class/** =roles["admin,normal,assistant"]
/grade/** =roles["admin,normal"]
/** = authc






测试


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





完整配置











	
		
			
		
		
	


	




	


	
	
		
		
		
		
			
				
					
						
						
						
					
				
			
		
		
	




	
	
		
		
		
		
			
			
					
				
			  
                      
                  
			
		
		
			
				/**/*.* = anon
				/login = anon
				/student/** =roles["admin,normal,assistant"]
				/teacher/** =roles["admin,normal,assistant"]
				/class/** =roles["admin,normal,assistant"]
				/grade/** =roles["admin,normal"]		
				/** = authc
			
		
	




你可能感兴趣的:(shiro,springMVC,java,web)