我想在Spring Boot应用程序中将特定的安全规则应用于2个URL。
我想使用AccessDecisionVoter功能来管理它。一切都很好...事件太好了。
我的新规则适用于我的2个特定URL,但不幸的是,该规则适用于我的所有URL。
我的AccessDecisionManager声明:
@Bean
public AccessDecisionManager playerResourceDecisionManager() {
List<AccessDecisionVoter<? extends Object>> decisionVoters = Arrays.asList(
new AuthenticatedVoter(),
hashSerialSecurityVoter
);
return new UnanimousBased(decisionVoters);
}
这是我的SecurityConfig主代码
http.csrf()
.disable().cors().and().exceptionHandling()
// All Login Stuff
.authenticationEntryPoint(new Http403ForbiddenEntryPoint() {})
.and().authenticationProvider(getProvider())
.formLogin().loginProcessingUrl("/login")
.successHandler(new AuthentificationLoginSuccessHandler())
.failureHandler(new SimpleUrlAuthenticationFailureHandler())
.and().logout().logoutUrl("/logout")
.logoutSuccessHandler(new AuthentificationLogoutSuccessHandler())
.invalidateHttpSession(true).and().authorizeRequests()
...
// Spring boot actuator - App Status
.antMatchers("/actuator/*").permitAll()
// Static Token end points
.antMatchers("/my-filtered-url1", "/sub/my-filtered-url2/*")
.permitAll()
.accessDecisionManager(playerResourceDecisionManager())
/* Here is the problem :
* I want this accessDescisionManager apply only on my antMatchers
* (2 specific URLs),
* But it runs on every app calls.
*/
.antMatchers(HttpMethod.POST, "/log/*").permitAll()
/* Login */
.antMatchers("/login").permitAll()
.antMatchers("/auth/**").permitAll()
.antMatchers(HttpMethod.POST,"/user/lost-password").permitAll()
.antMatchers("/user").hasAuthority("ADMIN")
.anyRequest().authenticated();
我不希望在带有URL声明的hashSerialSecurityVoter类中放入特定的代码。我该怎么办?
关于。
安全配置设置如下:
http
是构建器(类型HttpSecurity
)。
当您调用authorizeRequests()
时,它会为您提供第二个生成器(ExpressionInterceptUrlRegistry
)。
当您调用antMatchers()
时,它会为您提供第3个构建器(AuthorizedUrl
)。
[当您调用permitAll()
时,它将返回到第二个生成器。
这意味着您是在accessDecisionManager()
构建器而不是*Registry
构建器上调用AuthorizedUrl
,即,该调用是全局的,与匹配器无关。
您的缩进是错误的,这就是为什么您感到困惑的原因:
.antMatchers("/my-filtered-url1", "/sub/my-filtered-url2/*")
.permitAll()
.accessDecisionManager(playerResourceDecisionManager())
访问管理器及其底层的投票者不负责指定应将哪些访问规则应用于特定的URL,即访问表达式的工作应用于AuthorizedUrl
,例如
permitAll()
-access("permitAll")
的缩写
authenticated()
-access("authenticated")
的缩写
hasRole("ADMIN")
-access("hasRole('ROLE_ADMIN')")
的缩写
hasAuthority("HASHSERIAL")
-access("hasAuthority('HASHSERIAL')")
的缩写
。 。 。
因此,如果您希望自定义AccessDecisionVoter
对特定的URL进行投票,则可以实现投票者的supports(ConfigAttribute attribute)
方法以识别特定的属性,可以在全局范围内注册该投票者,然后指定特定的URL要求它:
.antMatchers("/my-filtered-url1", "/sub/my-filtered-url2/*")
.hasAuthority("HASHSERIAL")
class HashSerialSecurityVoter implements AccessDecisionVoter<Object> {
public boolean supports(ConfigAttribute attribute) {
if ((attribute.getAttribute() != null)
&& attribute.getAttribute().equals("HASHSERIAL")) {
return true;
}
else {
return false;
}
}
public boolean supports(Class<?> clazz) {
return true;
}
public int vote(Authentication authentication, Object object,
Collection<ConfigAttribute> attributes) {
// Your logic here
}
}
安德里亚的答案是正确的。特定的hashSerialSecurityVoter现在可以正常运行🙂
但是我希望所有默认端点都允许
我的代码:
...
.anyRequest()
.authenticated();
.accessDecisionManager(playerResourceDecisionManager());
@Bean
public AccessDecisionManager playerResourceDecisionManager() {
List<AccessDecisionVoter<? extends Object>> decisionVoters = Arrays.asList(
new AuthenticatedVoter(),
hashSerialSecurityVoter
);
return new UnanimousBased(decisionVoters);
}
它有效地通过了两个选民。但是在AuthenticatedVoter中,它没有按预期运行。
即使我已通过身份验证,它也会返回ACCESS_ABSTAIN值。当我调试它时,我注意到Manager不提供任何ConfigAttribute。因此authenticatedVoter.supports()
方法返回false。
我在accessDecisionManager声明上会错过什么吗?
结果是我的主要API客户端不再起作用,因为我的所有请求都返回403。