我通过 Spring Boot 1.59 使用 Spring Security,并且遇到了动态保护 URL 的问题
以下是我的配置方法:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
//.antMatchers("/home").access("hasAnyRole('ROLE_USER','ROLE_ADMIN')")
//.antMatchers("/home3").access("hasRole('ROLE_ADMIN')")
.and()
.formLogin().loginPage("/login").permitAll()
.loginProcessingUrl("/myLogin")
.usernameParameter("my_username").passwordParameter("my_password")
.defaultSuccessUrl("/home")
.and()
.logout()
.logoutUrl("/myLogout")
.logoutSuccessUrl("/login?logout")
.and()
.exceptionHandling().accessDeniedPage("/403")
.and()
.csrf().disable();
}
我有一个自定义的 FilterInvocationSecurityMetadataSource,如下所示:
@Component
public class CustomFilterInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource
{
protected Logger log = Logger.getLogger(CustomFilterInvocationSecurityMetadataSource.class.getName());
@Override
public Collection<ConfigAttribute> getAttributes(Object object)
{
FilterInvocation fi = (FilterInvocation) object;
String url = fi.getRequestUrl();
log.info("URL:" + url);
// Will eventually come from database
//List<ConfigAttribute> attributes = SecurityConfig.createList("permitAll");
//List<ConfigAttribute> attributes = SecurityConfig.createList("hasRole('ROLE_ADMIN')");
//List<ConfigAttribute> attributes = SecurityConfig.createList("ROLE_ADMIN");
List<ConfigAttribute> attributes = SecurityConfig.createList("permitAll");
if (!url.equalsIgnoreCase("/login") && !url.contains("/javax.faces.resource/") && !url.contains("/resources/images/"))
return attributes;
else
return null;
}
@Override
public Collection<ConfigAttribute> getAllConfigAttributes() {
return null;
}
@Override
public boolean supports(Class<?> clazz) {
return FilterInvocation.class.isAssignableFrom(clazz);
}
}
我有一个 BeanPostProcessor 用我的自定义 FilterInvocationSecurityMetadataSource 更新名称空间 FilterSecurityInterceptor:
@Component
public class MyFilterSecurityInterceptorBeanPostProcessor implements BeanPostProcessor {
@Autowired
CustomFilterInvocationSecurityMetadataSource customFilterInvocationSecurityMetadataSource;
@Override
public Object postProcessBeforeInitialization(Object bean, String name) throws BeansException {
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String name) throws BeansException {
if (bean instanceof FilterSecurityInterceptor) {
((FilterSecurityInterceptor) bean).setSecurityMetadataSource(customFilterInvocationSecurityMetadataSource);
}
return bean;
}
}
当我在 configure 方法中为/home 和/home3 的 antMatchers 并且不使用自定义 FilterInvocationSecurityMetadataSource 和 BeanPostProcessor 时,我可以毫无问题地到达/home 和/home3。
然而,我遇到的问题是,每当我注释掉 antMatchers 并尝试使用自定义 FilterInvocationSecurityMetadataSource 和 BeanPostProcessor 来提供访问角色时,我在尝试访问/home 和/home3 时会收到 403 Forbidden。
如果我从 CustomFilterInvocationSecurityMetadataSource 返回一个 null,它将允许请求成功通过,但任何返回任何访问角色的请求,包括'permitAll'都会返回 403.有没有人知道为什么会这样?我错过了什么吗?任何帮助是极大的赞赏!
谢谢!