Spring mvc Spring安全性:为什么不调用我的自定义AccessDecisionVoter
我正在尝试使用自定义的Spring mvc Spring安全性:为什么不调用我的自定义AccessDecisionVoter,spring-mvc,spring-security,spring-java-config,Spring Mvc,Spring Security,Spring Java Config,我正在尝试使用自定义的AccessDecisionVoter进行URL授权。我没有收到任何错误,调试表明我的投票者在启动时被选中。但是,在运行时,不会调用vote方法,因此允许每个经过身份验证的用户完全访问 注意,我不需要方法安全性。我也没有使用XML配置。这就排除了所有在互联网上发布的关于这个话题的例子 @Configuration @EnableWebSecurity @EnableWebMvc @ComponentScan @Order(-10) public class HttpSecu
AccessDecisionVoter
进行URL授权。我没有收到任何错误,调试表明我的投票者在启动时被选中。但是,在运行时,不会调用vote
方法,因此允许每个经过身份验证的用户完全访问
注意,我不需要方法安全性。我也没有使用XML配置。这就排除了所有在互联网上发布的关于这个话题的例子
@Configuration
@EnableWebSecurity
@EnableWebMvc
@ComponentScan
@Order(-10)
public class HttpSecurityConfig extends WebSecurityConfigurerAdapter {
@Value("${trusted_ports}")
private List<Integer> trustedPorts;
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private ServiceIdAwareVoter serviceIdAwareVoter;
RequestMatcher requestMatcher = new OrRequestMatcher(
// @formatter:off
new AntPathRequestMatcher("/**", GET.name()),
new AntPathRequestMatcher("/**", POST.name()),
new AntPathRequestMatcher("/**", DELETE.name()),
new AntPathRequestMatcher("/**", PATCH.name()),
new AntPathRequestMatcher("/**", PUT.name())
// @formatter:on
);
@Override
protected UserDetailsService userDetailsService() {
return userDetailsService;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(preAuthProvider());
auth.authenticationProvider(authProvider());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http.
httpBasic().and().
authorizeRequests().anyRequest().fullyAuthenticated().
accessDecisionManager(accessDecisionManager()).and().
csrf().disable().
logout().disable().
exceptionHandling().and().
sessionManagement().sessionCreationPolicy(STATELESS).and().
anonymous().disable().
addFilterAfter(preAuthFilter(), X509AuthenticationFilter.class).
addFilter(authFilter());
// @formatter:on
}
AccessDecisionManager accessDecisionManager() {
return new UnanimousBased(ImmutableList.of(serviceIdAwareVoter));
}
Filter preAuthFilter() throws Exception {
PreAuthenticationFilter preAuthFilter = new PreAuthenticationFilter(trustedPorts);
preAuthFilter.setAuthenticationManager(super.authenticationManager());
return preAuthFilter;
}
PreAuthenticatedAuthenticationProvider preAuthProvider() {
PreAuthenticatedAuthenticationProvider preAuthProvider = new PreAuthenticatedAuthenticationProvider();
UserDetailsByNameServiceWrapper<PreAuthenticatedAuthenticationToken> userDetailsServiceWrapper = new UserDetailsByNameServiceWrapper<>();
userDetailsServiceWrapper.setUserDetailsService(userDetailsService());
preAuthProvider.setPreAuthenticatedUserDetailsService(userDetailsServiceWrapper);
return preAuthProvider;
}
Filter authFilter() throws Exception {
AppIdAppKeyAuthenticationFilter authFilter = new AppIdAppKeyAuthenticationFilter(requestMatcher);
authFilter.setAuthenticationFailureHandler(new ExceptionStoringAuthenticationFailureHandler());
authFilter.setAuthenticationSuccessHandler(new UrlForwardingAuthenticationSuccessHandler());
authFilter.setAuthenticationManager(authenticationManagerBean());
return authFilter;
}
AuthenticationProvider authProvider() {
AppIdAppKeyAuthenticationProvider authProvider = new AppIdAppKeyAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService());
return authProvider;
}
@配置
@启用Web安全性
@EnableWebMvc
@组件扫描
@订单(-10)
公共类HttpSecurityConfig扩展了WebSecurity配置适配器{
@值(“${trusted_port}”)
私有列表托管端口;
@自动连线
私有用户详细信息服务用户详细信息服务;
@自动连线
私人服务IDawarevoter服务IDawarevoter;
RequestMatcher RequestMatcher=新的或RequestMatcher(
//@formatter:off
新的AntPathRequestMatcher(“/**”,GET.name()),
新的AntPathRequestMatcher(“/**”,POST.name()),
新的AntPathRequestMatcher(“/**”,DELETE.name()),
新的AntPathRequestMatcher(“/**”,PATCH.name()),
新的AntPathRequestMatcher(“/**”,PUT.name())
//@formatter:on
);
@凌驾
受保护的UserDetailsService UserDetailsService(){
返回userDetailsService;
}
@凌驾
受保护的无效配置(AuthenticationManagerBuilder auth)引发异常{
auth.authenticationProvider(preAuthProvider());
auth.authenticationProvider(authProvider());
}
@凌驾
受保护的无效配置(HttpSecurity http)引发异常{
//@formatter:off
http。
httpBasic()和()。
authorizeRequests().anyRequest().fullyAuthenticated()。
accessDecisionManager(accessDecisionManager())和()。
csrf().disable()。
注销()。禁用()。
异常处理()和()。
sessionManagement().sessionCreationPolicy(无状态)。和()。
匿名().disable()。
addFilterAfter(preAuthFilter(),X509AuthenticationFilter.class)。
addFilter(authFilter());
//@formatter:on
}
AccessDecisionManager AccessDecisionManager(){
返回新的UnanimousBased(不可变列表of(serviceIdAwareVoter));
}
Filter preAuthFilter()引发异常{
PreAuthenticationFilter preAuthFilter=新的PreAuthenticationFilter(trustedPorts);
preAuthFilter.setAuthenticationManager(super.authenticationManager());
返回预授权过滤器;
}
预验证身份验证提供程序预验证提供程序(){
PreAuthenticateAuthenticationProvider PreAuthenticationProvider=新的PreAuthenticateAuthenticationProvider();
UserDetailsByNameServiceWrapper userDetailsServiceWrapper=新的UserDetailsByNameServiceWrapper();
setUserDetailsService(userDetailsService());
setPreAuthenticatedUserDetailsService(userDetailsServiceWrapper);
返回预授权提供者;
}
Filter authFilter()引发异常{
AppIdAppKeyAuthenticationFilter authFilter=新的AppIdAppKeyAuthenticationFilter(请求匹配器);
authFilter.setAuthenticationFailureHandler(新的例外情况ToringAuthenticationFailureHandler());
setAuthenticationSuccessHandler(新的UrlForwardingAuthenticationSuccessHandler());
setAuthenticationManager(authenticationManagerBean());
返回过滤器;
}
AuthenticationProvider authProvider(){
AppIdAppKeyAuthenticationProvider authProvider=新的AppIdAppKeyAuthenticationProvider();
setUserDetailsService(userDetailsService());
返回authProvider;
}
您的配置说明您正在允许完全经过身份验证的用户在此访问:
authorizeRequests().anyRequest().fullyAuthenticated().
您正在告诉Spring Security授予对任何请求的访问权,只要它们经过完全身份验证。您的目标是什么?您如何试图通过角色/权限限制访问?我猜这是您在自定义投票者bean中口述的内容
通常,当您的安全级别发生冲突时,投票者bean就会发挥作用,例如,这里您说所有请求都具有完全访问权限,但是如果您的代码命中了一个具有类似这样的方法级别安全性的方法(不是一个非常真实的示例):
您将有投票者参与进来,因为您的java安全配置是“向所有人授予访问权”(投票赞成访问),但此方法注释是“不向任何人授予访问权”(投票反对访问)
在您的情况下,没有投票权,您授予每个人访问权限。背景: 经过数小时的调试,我发现了问题的根本原因,这是非常深刻的。部分原因是Spring Security Java配置的文档记录非常糟糕(为此我打开了一个。他们的示例以及大多数在线示例都是从XML配置中复制粘贴的,而世界可能从2010年开始停止使用Spring XML配置。另一部分原因是,REST服务安全性是Spring安全设计中的事后考虑,并且他们没有一流的支持来保护没有登录的应用程序页面、错误页面和常见的视图层。最后但并非最不重要的是,我的应用程序中有几个(mis)配置,所有这些都汇集在一起,形成了一个令人难以置信的完美风暴 技术背景: 使用
authorizeRequests()
配置一个ExpressionUrlAuthorizationConfigurer
,它最终使用WebExpressionVoter
设置一个Unanimoused
AccessDecisionManager
。如果身份验证成功,将从FilterSecurityInterceptor
调用此AccessDecisionManager
(显然,如果
@PreAuthrorize("permitNone")
public void someMethod{
...
}
private Dynamic registerCorsFilter(ServletContext ctx) {
Dynamic registration = ctx.addFilter("CorsFilter", CorsFilter.class);
registration.addMappingForUrlPatterns(getDispatcherTypes(), false, "/*");
return registration;
}
private EnumSet<DispatcherType> getDispatcherTypes() {
return (isAsyncSupported() ? EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.INCLUDE, DispatcherType.ASYNC)
: EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.INCLUDE));
}
public int vote(Authentication authentication, FilterInvocation fi,
Collection<ConfigAttribute> attributes) {
}