表决器 抽象类 AbstractAccessDecisionManager 有个属性allowIfAllAbstainDecisions= false,相关方法checkAllowIfAllAbstainDecisions()
protected final void checkAllowIfAllAbstainDecisions() {
if (!this.isAllowIfAllAbstainDecisions()) {
throw new AccessDeniedException(messages.getMessage(
"AbstractAccessDecisionManager.accessDenied", "Access is denied"));
}
}
AffirmativeBased、ConsensusBased、UnanimousBased 三个表决最后都会调用checkAllowIfAllAbstainDecisions()到了这一步,说明所有投票器都弃权。那么默认情况下,调用这个方法访问拒绝
权限拦截器 FilterSecurityInterceptor 属性 observeOncePerRequest = true 默认为真,字面意思监控每一次请求
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);
}
}
有些动态权限实现方法是在 FilterSecurityInterceptor 后增加自定义过滤器
在FilterSecurityInterceptor 处理后,已经对此请求添加了已经处理的标识,所以自定义 FilterSecurityInterceptor 就直接跳过,不再处理。
自定义过滤器可以将observeOncePerRequest属性设为假,或者直接改变有误处理的attribute的key,跟父类不同也可以