转载地址:https://blog.csdn.net/qq_20597149/article/details/78493020?locationNum=1&fps=1
1. shiro的filter介绍
<bean id=”shiroFilter” class=”org.apache.shiro.spring.web.ShiroFilterFactoryBean”>
<property name=”securityManager” ref=”securityManager” />
<property name=”loginUrl” value=”/login” />
<property name=”successUrl” value=”/home” />
<property name=”unauthorizedUrl” value=”/unauthorized” />
<!– filters一般不需要定义,除非自定义filter覆盖原来的时候,需要定义 –>
<!– <property name=”filters”>
<map>
<entry key=”authc”>
<bean class=”org.apache.shiro.web.filter.authc.PassThruAuthenticationFilter” />
</entry>
</map>
</property> –>
<property name=”filterChainDefinitions”>
<value>
/admin = authc,roles[admin]
/edit = authc,perms[admin:edit]
/home = user
/** = anon
</value>
</property>
</bean>
loginUrl: 当用户没有登录的时候,会重发一个login请求,引导用户去登录
successUrl:是当用户登录成功,转发home请求
unauthorizedUrl指如果请求失败,重发/unauthorized请求,引导用户到认证异常错误页面
<property name=”filters”>
<map>
<entry key=”authc”>
<bean class=”org.apache.shiro.web.filter.authc.PassThruAuthenticationFilter” />
</entry>
</map>
</property>
由此一来,如果有些特殊的请求需要特殊处理,就可以自己写一个filter,添加一个别名,如:
<property name=”filters”>
<map>
<entry key=”new”>
<bean class=”com.text.newFilter” />
</entry>
</map>
</property>
2. shiro自定义filter
使用shiro的时候,比较常用的filter有anon,authc,roles和perms。当我们想定义某个链接是拥有某些权限的用户才可以访问的时候,我们可以这样定义。/xx = roles[A,B]。在shiro中,表示当前用户同时拥有A,B两种角色才可以访问/xx这个链接,是一种&&(与)的关系
RolesAuthorizationFilter这样一个类,这个类就是定义roles的filter。
01 | public class RolesAuthorizationFilter extends AuthorizationFilter { |
05 | @SuppressWarnings ({ "unchecked" }) |
06 | public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException { |
08 | Subject subject = getSubject(request, response); |
09 | String[] rolesArray = (String[]) mappedValue; |
11 | if (rolesArray == null || rolesArray.length == 0 ) { |
16 | Set<String> roles = CollectionUtils.asSet(rolesArray); |
17 | return subject.hasAllRoles(roles); |
上面定义了subject.hasAllRoles(roles);就是当前用户必须拥有定义的所有角色才会返回true。但有时候,我们需要当前用户拥有定义的其他一个角色就可以访问,那就需要写自己的filter。也很简单,代码以下:
01 | public class AnyRolesAuthorizationFilter extends AuthorizationFilter { |
05 | protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception { |
07 | Subject subject = getSubject(request, response); |
08 | String[] rolesArray = (String[]) mappedValue; |
10 | if (rolesArray == null || rolesArray.length == 0 ) { |
15 | Set<String> roles = CollectionUtils.asSet(rolesArray); |
16 | for (String role : roles) { |
17 | if (subject.hasRole(role)) { |
从上面的代码可以看到,当遍历,发现当前用户拥有定义的其中一个角色就立刻返回true,否则返回false。
定义好filter,只需要代码默认的roles即可。
01 | < bean id = "shiroFilter" class = "org.apache.shiro.spring.web.ShiroFilterFactoryBean" > |
02 | < property name = "securityManager" ref = "securityManager" /> |
03 | < property name = "loginUrl" value = "/security/login.html" /> |
04 | < property name = "successUrl" value = "/home.html" /> |
05 | < property name = "unauthorizedUrl" value = "/security/unauthorized.html" /> |
06 | < property name = "filters" > |
08 | < entry key = "anyRoles" value-ref = "anyRolesAuthorizationFilter" /> |
11 | < property name = "filterChainDefinitions" > |
13 | /admin = anyRoles[admin1,admin2] |
perms的filter也同理。看看源码:
01 | public class PermissionsAuthorizationFilter extends AuthorizationFilter { |
03 | //TODO - complete JavaDoc |
05 | public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException { |
07 | Subject subject = getSubject(request, response); |
08 | String[] perms = (String[]) mappedValue; |
10 | boolean isPermitted = true; |
11 | if (perms != null && perms.length > 0) { |
12 | if (perms.length == 1) { |
13 | if (!subject.isPermitted(perms[0])) { |
17 | if (!subject.isPermittedAll(perms)) { |
自定义的filter:
01 | public class AnyPermissionsAuthorizationFilter extends AuthorizationFilter { |
04 | protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception { |
05 | Subject subject = getSubject(request, response); |
06 | String[] perms = (String[]) mappedValue; |
08 | for (String perm : perms) { |
09 | if (subject.isPermitted(perm)) { |
配置使用自定义filter
01 | < bean id = "shiroFilter" class = "org.apache.shiro.spring.web.ShiroFilterFactoryBean" > |
02 | < property name = "securityManager" ref = "securityManager" /> |
03 | < property name = "loginUrl" value = "/security/login.html" /> |
04 | < property name = "successUrl" value = "/home.html" /> |
05 | < property name = "unauthorizedUrl" value = "/security/unauthorized.html" /> |
06 | < property name = "filters" > |
08 | < entry key = "anyPerms" value-ref = "anyPermissionsAuthorizationFilter" /> |
13 | /admin/add = anyPerms["admin:delete","admin:add"] |
当用户请求/admin/add时,就会调用自定义的AnyPermissionsAuthorizationFilter来执行。