是否需要将自定义筛选器放在特定内置筛选器之前,以确保在执行该筛选器之后执行授权步骤?
你的过滤器
必须
来之前
FilterSecurityInterceptor
,因为这是进行授权和身份验证的地方。此筛选器是最后调用的筛选器之一。
至于你的过滤器的最佳位置在哪里,那要看情况了。例如,你真的希望你的过滤器出现在
AnonymousAuthenticationFilter
因为如果没有,未经身份验证的用户将始终使用
AnonymousAuthenticationToken
在调用筛选器时。
您可以签出过滤器的默认顺序
FilterComparator
是的。这个
AbstractPreAuthenticatedProcessingFilter
几乎与你正在做的事情相对应——它按照过滤器的顺序排列,让你知道你可以把你的东西放在哪里。无论如何,你的过滤器的顺序应该没有问题。
在请求周期中,何时进行antmatcher/hasrole检查?
所有这些都发生在
过滤器安全接收器
,更确切地说,在它的父级
AbstractSecurityInterceptor
以下内容:
protected InterceptorStatusToken beforeInvocation(Object object) {
Collection<ConfigAttribute> attributes = this.obtainSecurityMetadataSource()
.getAttributes(object);
if (attributes == null || attributes.isEmpty()) {
...
}
...
Authentication authenticated = authenticateIfRequired();
// Attempt authorization
try {
this.accessDecisionManager.decide(authenticated, object, attributes);
}
catch (AccessDeniedException accessDeniedException) {
...
throw accessDeniedException;
}
额外信息:
实质上,
过滤器安全接收器
有一个
ExpressionBasedFilterInvocationSecurityMetadataSource
包含
Map<RequestMatcher, Collection<ConfigAttribute>>
是的。在运行时,将根据
Map
看看有没有
RequestMatcher
钥匙是匹配的。如果是,一个
Collection<ConfigAttribute>
传递给
AccessDecisionManager
,最终要么授予访问权,要么拒绝访问。违约
访问决策管理器
是
AffirmativeBased
包含对象(通常是
WebExpressionVoter
)收集
ConfigAttribute
通过反射调用
SpelExpression
对应于你的
"hasRole('METADATA_CURATORZ')"
反对
SecurityExpressionRoot
对象初始化为
Authentication
是的。
我是否需要更改我在安全配置链中调用的内容的顺序,以及如何理解当前编写的配置?它显然没有做我认为应该做的事。
不,你的过滤器应该没有问题。作为旁注,除了你的
configure(HttpSecurity http)
方法,
WebSecurityConfigurerAdapter
扩展自具有一些默认值:
http
.csrf().and()
.addFilter(new WebAsyncManagerIntegrationFilter())
.exceptionHandling().and()
.headers().and()
.sessionManagement().and()
.securityContext().and()
.requestCache().and()
.anonymous().and()
.servletApi().and()
.apply(new DefaultLoginPageConfigurer<>()).and()
.logout();
你可以看看
HttpSecurity
如果你想确切地看到它们做什么和添加什么过滤器。
问题
当您执行以下操作时:
.authorizeRequests()
.antMatchers("/admin/test").hasRole("METADATA_CURATORZ")
…搜索的角色是
"ROLE_METADATA_CURATORZ"
.为什么?
ExpressionUrlAuthorizationConfigurer
的静态
hasRole(String role)
方法结束处理
"METADATA_CURATORZ"
以下内容:
if (role.startsWith("ROLE_")) {
throw new IllegalArgumentException(
"role should not start with 'ROLE_' since it is automatically inserted. Got '"
+ role + "'");
}
return "hasRole('ROLE_" + role + "')";
}
所以你的授权表达式变成
"hasRole('ROLE_METADATA_CURATORZ'"
最后调用方法
hasRole('ROLE_METADATA_CURATORZ')
在
安全表达式根
,进而搜索角色
ROLE_METADATA_CURATORZ
在
身份验证
的权威。
解决方案
改变
SimpleGrantedAuthority myrole = new SimpleGrantedAuthority("METADATA_CURATORZ");
致:
SimpleGrantedAuthority myrole = new SimpleGrantedAuthority("ROLE_METADATA_CURATORZ");