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

来源:互联网 发布:自动化软件开发工程师 编辑:程序博客网 时间:2024/05/19 06:35

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配置:

 <!-- 自定义的过滤器,用来判断当前用户是否是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即可。