我通过 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.有没有人知道为什么会这样?我错过了什么吗?任何帮助是极大的赞赏!

谢谢!