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即可。