1. 前言
访问的路径需要什么样的角色和权限? 它就是 FilterSecurityInterceptor
,正是我们需要的那个轮子。
2.FilterSecurityInterceptor
过滤器排行榜第 32 位!肩负对 http 接口权限认证的重要职责。我们来看它的过滤逻辑:
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
FilterInvocation fi = new FilterInvocation(request, response, chain);
invoke(fi);
}
初始化了一个 FilterInvocation
然后被 invoke
方法处理:
public void invoke(FilterInvocation fi) throws IOException, ServletException {
if ((fi.getRequest() != null)
&& (fi.getRequest().getAttribute(FILTER_APPLIED) != null)
&& observeOncePerRequest) {
// filter already applied to this request and user wants us to observe
// once-per-request handling, so don't re-do security checking
fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
}
else {
// first time this request being called, so perform security checking
if (fi.getRequest() != null && observeOncePerRequest) {
fi.getRequest().setAttribute(FILTER_APPLIED, Boolean.TRUE);
}
InterceptorStatusToken token = super.beforeInvocation(fi);
try {
fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
}
finally {
super.finallyInvocation(token);
}
super.afterInvocation(token, null);
}
}
每一次请求被 Filter
过滤都会被打上标记 FILTER_APPLIED
,没有被打上标记的 走了父类的 beforeInvocation
方法然后再进入过滤器链,看上去是走了一个前置的处理。那么前置处理了什么呢?
首先会通过 this.obtainSecurityMetadataSource().getAttributes(Object object)
拿受保护对象(就是当前请求的 URI)所有的映射角色(ConfigAttribute
直接理解为角色的进一步抽象) 。然后使用访问决策管理器 AccessDecisionManager
进行投票决策来确定是否放行。 我们来看一下这两个接口。
安全拦截器和“安全对象”模型参考:
3. 元数据加载器
元数据加载器 FilterInvocationSecurityMetadataSource
是 FilterSecurityInterceptor
的属性,UML 图如下:
FilterInvocationSecurityMetadataSource
是一个标记接口,其抽象方法继承自 SecurityMetadataSource``AopInfrastructureBean
。
- Collection getAttributes(Object object)