ShiroFilter拦截
上面的ShiroFilter中有如下图的代码
这主要是用来定义ShiroFilter拦截哪些请求,以及怎么拦截请求的。
拦截器链
在上图中,左边是url,右边是拦截器。
常见的拦截器有:
- anon:任何人都可以访问
- authc:只有认证后才可以访问
- logout:只有登录后才可以访问
- roles[角色名]:只有拥有特定角色才能访问,例如
/admin.jsp = roles[user]
- perms["行为"]:只有拥有某种行为的才能访问,例如
/admin/deluser = prems["user:delete"]
- 想了解更多拦截器,可以参考
shiro.apache.org/web.html#default-filters
url匹配
- 在上图中,有用到
/**
,这是代表所有请求,是为了拦截其余未定义拦截规则的请求。 - 其实这透露了url匹配是从上到下的,比如login.jsp由于前面定义了
/login.jsp = anon
,所以就不会交给/**
来拦截了。 - 另外,是可以有多个拦截器的,所以
/admin/** = authc, roles[administrator]
也是可以的。
url属性
上面的ShiroFilter还配置了下图的属性,这是用来定义发生一些情况时跳转到哪个页面的。
- 比如配置了loginUrl,那么发起未认证的请求都会跳转到loginUrl
- successUrl是用来定义登录成功后调整到哪个页面(如果controller跳转了视图那么这个失效)
- unauthorizedUrl是用来定义访问不是自己权限的时跳转到哪个页面(普通的authc不会触发,roles会触发。)。
拦截器链的自定义
在上面都是使用硬编码的方式来定义拦截器链。下面将解决这个硬编码问题
一种方法是使用FilterChainResolver来处理,这里使用map的方式来处理。
定义一个类,核心方法是返回一个LinkedHashMap【有序是为了确保从上到下匹配】:
复制代码
package com.progor.utils;
import java.util.LinkedHashMap;
public class FilterChainMap {
// 使用静态工厂
public static LinkedHashMap<String, String> getFilterChainMap(){
LinkedHashMap<String, String> map = new LinkedHashMap<>();
// 下面的数据可以从数据库中查询出来。
map.put("/login.jsp", "anon");
map.put("/shiro/login", "anon");
map.put("/shiro/logout", "logout");
map.put("/admin.jsp", "authc");
map.put("/**", "authc");
return map;
}
}
修改applicationContext.xml:
复制代码
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager"/>
<property name="loginUrl" value="/login.jsp"/>
<property name="successUrl" value="/list.jsp"/>
<property name="unauthorizedUrl" value="/unauthorized.jsp"/>
<property name="filterChainDefinitionMap" ref="filteChainMap"></property>
<!--去掉filterChainDefinitions-->
</bean>
<!--核心是获取这个map,由于使用了静态工厂,所以这样定义这个bean-->
<bean id="filteChainMap" class="com.progor.utils.FilterChainMap" factory-method="getFilterChainMap" ></bean>
补充:
上面讲述了ShiroFilter的配置,解决了请求的拦截问题。