您的位置:首页 > 其它

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

2017-03-08 19:54 996 查看

情况介绍

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。增加一个对应如下:
<!-- shiroFilter -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean" >
<property name="securityManager" ref="securityManager" />
<property name="loginUrl" value="/login" />
<property name="unauthorizedUrl" value="/403" />
<property name="filters">
<map>
<entry key="roles">  
                    <bean  
                        class="com.test.web.support.shiro.CustomRolesAuthorizationFilter" />  
                </entry>  
</map>
</property>
<property name="filterChainDefinitions">
<value>
/**/*.* = anon
/login = anon
/student/** =roles["admin,normal,assistant"]
/teacher/** =roles["admin,normal,assistant"]
/class/** =roles["admin,normal,assistant"]
/grade/** =roles["admin,normal"]
/** = authc
</value>
</property>
</bean>

需要注意的是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的验证。<!-- shiroFilter -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean" >
<property name="securityManager" ref="securityManager" />
<property name="loginUrl" value="/login" />
<property name="unauthorizedUrl" value="/403" />
<property name="filters">
<map>
<entry key="authc">
<bean
class="com.test.web.support.shiro.AjaxCompatibleAuthenticationFilter"></bean>
</entry>
<entry key="roles">  
                    <bean  
                        class="com.test.web.support.shiro.CustomRolesAuthorizationFilter" />  
                </entry>  
</map>
</property>
<property name="filterChainDefinitions">
<value>
/**/*.* = anon
/login = anon
/student/** =roles["admin,normal,assistant"]
/teacher/** =roles["admin,normal,assistant"]
/class/** =roles["admin,normal,assistant"]
/grade/** =roles["admin,normal"]
/** = authc
</value>
</property>
</bean>

测试

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

完整配置

<?xml version="1.0" encoding="UTF-8"?>
<!-- ~ Licensed to the Apache Software Foundation (ASF) under one ~ or more
contributor license agreements. See the NOTICE file ~ distributed with this
work for additional information ~ regarding copyright ownership. The ASF
licenses this file ~ to you under the Apache License, Version 2.0 (the ~
"License"); you may not use this file except in compliance ~ with the License.
You may obtain a copy of the License at ~ ~ http://www.apache.org/licenses/LICENSE-2.0 ~ ~ Unless required by applicable law or agreed to in writing, ~ software
distributed under the License is distributed on an ~ "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY ~ KIND, either express or implied. See the
License for the ~ specific language governing permissions and limitations
~ under the License. -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

<bean id="mongoRealm" class="com.test.web.support.shiro.MyShiro">
<property name="credentialsMatcher">
<bean class="org.apache.shiro.authc.credential.SimpleCredentialsMatcher"></bean>
</property>
<property name="mongoTemplate" ref="mongoTemplate" />
</bean>

<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />

<!-- securityManager -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<!-- <property name="cacheManager" ref="cacheManager" /> -->
<!-- <property name="sessionManager" ref="sessionManager" /> -->
<!-- Single realm app. If you have multiple realms, use the 'realms' property
instead. -->
<property name="rememberMeManager">
<bean class="org.apache.shiro.web.mgt.CookieRememberMeManager">
<property name="cookie">
<bean class="org.apache.shiro.web.servlet.SimpleCookie">
<constructor-arg value="sid" />
<!--设置Cookie名字,默认为JSESSIONID -->
<property name="name" value="WEBSID" />
</bean>
</property>
</bean>
</property>
<property name="realm" ref="mongoRealm" />
</bean>

<!-- shiroFilter -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean" >
<property name="securityManager" ref="securityManager" />
<property name="loginUrl" value="/login" />
<property name="unauthorizedUrl" value="/403" />
<property name="filters">
<map>
<entry key="authc">
<bean
class="com.test.web.support.shiro.AjaxCompatibleAuthenticationFilter"></bean>
</entry>
<entry key="roles">
<bean
class="com.test.web.support.shiro.CustomRolesAuthorizationFilter" />
</entry>
</map>
</property>
<property name="filterChainDefinitions">
<value>
/**/*.* = anon
/login = anon
/student/** =roles["admin,normal,assistant"]
/teacher/** =roles["admin,normal,assistant"]
/class/** =roles["admin,normal,assistant"]
/grade/** =roles["admin,normal"]
/** = authc
</value>
</property>
</bean>
</beans>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: