当前位置: 代码迷 >> 综合 >> spring-shiro实现角色(roles)自定义Filter----配置多个角色的或关系
  详细解决方案

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

热度:53   发布时间:2023-10-20 13:35:17.0

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{
    @Overrideprotected 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配置:

 <!-- 自定义的过滤器,用来判断当前用户是否是roles["admin,operator"]中的某个角色 -->  <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监控页面允许访问 -->/druid/** = anon<!--角色认证-->/desktop/edit=authc roleOrFilter["operator,admin"]</property>

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

  相关解决方案