动态保护URL的Spring Security问题

时间:2018-02-06 04:46:07

标签: spring spring-mvc spring-boot spring-security

我通过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,它将允许请求成功通过,但任何返回任何访问角色的请求,包括&#39; permitAll&#39;返回403.有谁知道为什么会这样?我错过了什么吗?非常感谢任何帮助!

谢谢!

0 个答案:

没有答案