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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/q383965374/article/details/60880050



情况介绍


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>



猜你喜欢

转载自blog.csdn.net/q383965374/article/details/60880050