spring-shiro实现角色(roles)自定义Filter----配置多个角色的或关系

roles:正常情况下URL路径的拦截设置如下:
/admins/user/**=roles[admin]
参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,当有多个参数时,例如/admins/user/**=roles[“admin,guest”]
但是这个设置方法是需要每个参数满足才算通过,相当于hasAllRoles()方法。也就是我们的角色必须同时拥有admin和guest权限才可以。

我们可以看到其实这个roles的filter是通过subject.hasAllRoles(roles)判断是否满足所有权限,但是我们真实项目中,很多时候用户只要满足其中一个角色即可认为是授权认证成功。
apache shiro 的角色过滤是 and的关系,需要重新写成or的关系。
新建类CustomRolesAuthorizationFilter.java

package cn.easted.edm.core.security;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authz.AuthorizationFilter;

/**
 * 实现roles["admin,test"]或关系
 * @ClassName:CustomRolesAuthorizationFilter
 * @author:Wanghao
 * @date: 2017年9月27日 下午5:27:58
 */
public class CustomRolesAuthorizationFilter extends AuthorizationFilter{

    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue)
            throws Exception {
         Subject subject = getSubject(request, response);  
            String[] rolesArray = (String[]) mappedValue;  
            //没有角色限制,有权限访问  
            if (rolesArray == null || rolesArray.length == 0) { 
                return true;  
            }  
            for (int i = 0; i < rolesArray.length; i++) {  
                 //若当前用户是rolesArray中的任何一个,则有权限访问  
                if (subject.hasRole(rolesArray[i])) {
                    return true;  
                }  
            }    
            return false;  
    }
}

修改shiro配置:

   
    <bean id="roleOrFilter" class="cn.easted.edm.core.security.CustomRolesAuthorizationFilter" />

    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <property name="securityManager" ref="securityManager"/>
        <property name="loginUrl" value="/login"/>
        <property name="successUrl" value="/dashboard/list"/>
        <property name="unauthorizedUrl" value="/401"/>
        <property name="filters">  
            <map>    
                 <entry key="roleOrFilter" value-ref="roleOrFilter"/>
            map> 

        property>
         <property name="filterChainDefinitions">
            <value>
              
               /app/** = anon
               /assets/** = anon
               /static/** = anon
                /index.html = anon
              
               /login = anon
               /logout = anon
              
               /druid/** = anon
              
                /desktop/edit=authc roleOrFilter["operator,admin"]
       property>

需要注意的是filters中的entry 的key现在是roleOrFilter,这里需要与filterChainDefinitions中的拦截方法 roleOrFilter对应。(shiro默认使用的是roles)。
重写多个 在filters的map中并列增加map即可。

你可能感兴趣的:(spring)