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

    xiaoxiao2021-03-25  138

    情况介绍

    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>

    转载请注明原文地址: https://ju.6miu.com/read-5255.html

    最新回复(0)