在配置 Spring Security 时,必须为 AbstractSecurityInterceptor 设置一个 AccessDecisionManager。例如,下面的代码示例中,我们为 FilterSecurityInterceptor 配置了一个 AffirmativeBased 的 AccessDecisionManager:
@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
@Autowired
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// ...
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/user/**").hasAnyRole("ADMIN", "USER")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
// Set AccessDecisionManager for FilterSecurityInterceptor
http
.addFilterBefore(new MyFilterSecurityInterceptor(), FilterSecurityInterceptor.class)
.authorizeRequests()
.anyRequest().authenticated();
}
private static class MyFilterSecurityInterceptor extends FilterSecurityInterceptor {
@Autowired
public void setMyAccessDecisionManager(AccessDecisionManager accessDecisionManager) {
super.setAccessDecisionManager(accessDecisionManager);
}
}
@Bean
public AccessDecisionManager accessDecisionManager() {
List> decisionVoters = Collections.singletonList(new RoleVoter());
return new AffirmativeBased(decisionVoters);
}
}
在上面的例子中,我们创建了一个名为 MyFilterSecurityInterceptor 的子类,然后注入了一个 AffirmativeBased 的 AccessDecisionManager。最后,我们将 MyFilterSecurityInterceptor 添加到了 Spring Security 的过滤器链中,并为所有请求设置了访问限制。这样,就成功地解决了 AbstractSecurityInterceptor 必须提供一个非空的 AccessDecisionManager 的问题。