第八章 拦截器机制(二) 拦截器链

Shiro 对Servlet 容器的FilterChain 进行了代理,即ShiroFilter 在继续Servlet 容器的Filter链的执行之前,通过ProxiedFilterChain 对Servlet 容器的FilterChain 进行了代理;即先走Shiro 自己的Filter 体系,然后才会委托给Servlet 容器的FilterChain 进行Servlet 容器级别的Filter链执行

Shiro的ProxiedFilterChain执行流程:

1、先执行Shiro自己的Filter链;

2、再执行Servlet容器的Filter链(即原始的Filter)。

而 ProxiedFilterChain 是通过FilterChainResolver 根据配置文件中[urls]部分是否与请求的URL是否匹配解析得到的。

FilterChain getChain(ServletRequest request, ServletResponse response, FilterChain originalChain);

即传入原始的chain得到一个代理的chain。

Shiro 内部提供了一个路径匹配的FilterChainResolver 实现:PathMatchingFilterChainResolver,其根据[urls]中配置的url 模式(默认Ant 风格)=拦截器链和请求的url是否匹配来解析得到配置的拦截器链的;而PathMatchingFilterChainResolver内部通过FilterChainManager维护着拦截器链,比如DefaultFilterChainManager实现维护着url 模式与拦截器链的关系。因此我们可以通过FilterChainManager 进行动态动态增加url模式与拦截器链的关系。

DefaultFilterChainManager 会默认添加org.apache.shiro.web.filter.mgt.DefaultFilter 中声明的拦截器:

public enum DefaultFilter {
anon(AnonymousFilter.class),
authc(FormAuthenticationFilter.class),
authcBasic(BasicHttpAuthenticationFilter.class),
logout(LogoutFilter.class),
noSessionCreation(NoSessionCreationFilter.class),
perms(PermissionsAuthorizationFilter.class),
port(PortFilter.class),
rest(HttpMethodPermissionFilter.class),
roles(RolesAuthorizationFilter.class),
ssl(SslFilter.class),
user(UserFilter.class);
}

下一节会介绍这些拦截器的作用。


如果要注册自定义拦截器,IniSecurityManagerFactory/WebIniSecurityManagerFactory在启动时会自动扫描ini 配置文件中的[filters]/[main]部分并注册这些拦截器到DefaultFilterChainManager;且创建相应的url 模式与其拦截器关系链。如果使用Spring 后续章节会介绍如果注册自定义拦截器。


如果想自定义FilterChainResolver,可以通过实现WebEnvironment接口完成:

public class MyIniWebEnvironment extends IniWebEnvironment{
	protected FilterChainResolver createFilterChainResolver() {
		//在此处扩展自己的FilterChainResolver
		return super.createFilterChainResolver();
	}
}

如果覆盖了IniWebEnvironment 默认的FilterChainResolver,需要自己来解析请求与FilterChain 之间的关系。如果想动态实现url-拦截器的注册,就可以通过实现此处的FilterChainResolver来完成,比如:

public class MyIniWebEnvironment extends IniWebEnvironment{
	protected FilterChainResolver createFilterChainResolver() {
		//在此处扩展自己的FilterChainResolver
		//1. 创建FilterChainResolver
		PathMatchingFilterChainResolver filterChainResolver = new PathMatchingFilterChainResolver();
		//2. 创建FilterChainManager
		DefaultFilterChainManager filterChainManager = new DefaultFilterChainManager();
		//3. 注册Filter
		for(DefaultFilter filter:DefaultFilter.values()){
			filterChainManager.addFilter(filter.name(), (Filter) ClassUtils.newInstance(filter.getFilterClass()));
		}
		//4. 注册URL-Filter的映射关系
		filterChainManager.addToChain("/login.jsp", "authc");
		filterChainManager.addToChain("/unauthorized.jsp", "anon");
		filterChainManager.addToChain("/**", "authc");
		filterChainManager.addToChain("/**", "roles","admin");
		//5. 设置Filter的属性
		FormAuthenticationFilter authcFilter = (FormAuthenticationFilter) filterChainManager.getFilter("authc");
		authcFilter.setLoginUrl("/login.jsp");
		RolesAuthorizationFilter rolesFilter = (RolesAuthorizationFilter) filterChainManager.getFilter("roles");
		rolesFilter.setUnauthorizedUrl("/unauthorized.jsp");
		
		filterChainResolver.setFilterChainManager(filterChainManager);
		return filterChainResolver;
	}
}

此处自己去实现注册filter,及url 模式与filter 之间的映射关系。可以通过定制FilterChainResolver或FilterChainManager来完成诸如动态URL匹配的实现。


然后再web.xml中进行如下配置Environment:

<context-param>
	<param-name>shiroEnvironmentClass</param-name>
	<param-value>com.github.zhangkaitao.shiro.chapter8.web.env.MyIniWebEnvironment</param-value>
</context-param>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值