1

我有一个 Spring Boot 应用程序,其中有自定义预身份验证过滤器。我想忽略健康 URL 的安全性,但我做不到。下面是我的配置。

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Order(1000)
public class UserSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken> userDetailsService;

    @Autowired
    private IUserIdentityService iUserIdentityService;

    @Value("${spring.profiles.active}")
    private String profileType;
    
    @Autowired
    @Qualifier("publicEndpoints")
    private Map<String, String> publicEndpoints;
    
    @Autowired
    private GenericDataService genericDataService;

    @Bean(name = "preAuthProvider")
    PreAuthenticatedAuthenticationProvider preauthAuthProvider() {
        PreAuthenticatedAuthenticationProvider provider = new PreAuthenticatedAuthenticationProvider();
        provider.setPreAuthenticatedUserDetailsService(userDetailsService);
        return provider;
    }

    @Bean
    AppPreAuthenticatedProcessingFilter appPreAuthenticatedProcessingFilter() throws Exception {
        appPreAuthenticatedProcessingFilter filter = new appPreAuthenticatedProcessingFilter(iUserIdentityService, genericDataService);
        filter.setAuthenticationManager(super.authenticationManagerBean());
        filter.setContinueFilterChainOnUnsuccessfulAuthentication(false);
        filter.setCheckForPrincipalChanges(true);
        return filter;
    }

    /**
     * Uses JEE pre-authentication filter, that assumes that the user has been
     * pre-authenticated into the container.
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/health/e2e").permitAll()
                .and()
            .addFilter(appPreAuthenticatedProcessingFilter())
            .authorizeRequests()
                .anyRequest().authenticated()
                .and()
            .authenticationProvider(preauthAuthProvider())
            .csrf()
                .csrfTokenRepository(this.csrfTokenRepository())
                .and()
            .httpBasic().disable();
        // Disabling the CSRF implementation, if "csrf.disabled" property set to "true"
        // in System Properties.
        if (!StringUtils.isEmpty(profileType) && profileType.equals("local")) {
            http.csrf().disable();
        }
    }
    
    /**
     * Method to ignore web security for urls
     */
    @Override
    public void configure(WebSecurity web) throws Exception {
        web
           .ignoring()
               .antMatchers("*/api-docs", "/configuration/ui", "/swagger-resources/**", "/configuration/**", "/swagger-ui.html", "/webjars/**", "/health/e2e", "*/health/e2e", "**/health/e2e");

    }

    /**
     * Method to to return CsrfTokenRepository
     */
    private CsrfTokenRepository csrfTokenRepository() {
        CookieCsrfTokenRepository tokenRepository = CookieCsrfTokenRepository.withHttpOnlyFalse();
        tokenRepository.setCookiePath("/");
        return tokenRepository;
    }

}

自定义身份验证过滤器看起来像

@Slf4j
public class AppPreAuthenticatedProcessingFilter extends AbstractPreAuthenticatedProcessingFilter {

    private IUserIdentityService iUserIdentityService;
    
    private GenericDataService genericDataService;

    public AppPreAuthenticatedProcessingFilter(IUserIdentityService iUserIdentityService, GenericDataService genericDataService) {
        this.iUserIdentityService = iUserIdentityService;
        this.genericDataService = genericDataService;
    }

    @Override
    protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) {
        RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request));
        return iUserIdentityService.getUserName();
    }

    @Override
    protected Object getPreAuthenticatedCredentials(HttpServletRequest request) {
        return AppConst.DEFAULT_CREDENTIAL;
    }
}

我不确定为什么/health/e2e是安全的?

PS我尝试@Bean从预授权过滤器中删除,但在这种情况下,过滤器永远不会被任何请求调用。

4

1 回答 1

0

问题是两个方面

  1. 您的安全设置包含错误
  2. 过滤器也被添加到常规过滤器 bean 中。

使用您当前的安全设置,AppPreAuthenticatedProcessingFilter仅将其添加到/health/e2dURL。你试图修复某些东西实际上已经破坏了一些东西。

您的配置应该类似于

http.authorizeRequests().anyRequest().authenticated()
    .and().httpBasic()
    .and().authenticationProvider(preauthAuthProvider())
    .csrf().csrfTokenRepository(this.csrfTokenRepository())
    .and().addFilterBefore(appPreAuthenticatedProcessingFilter(), UsernamePasswordAuthenticationFilter.class);

    // in System Properties.
if (!StringUtils.isEmpty(profileType) && profileType.equals("local")) {
    http.csrf().disable();
}

Spring Boot 默认会javax.servlet.Filter在普通过滤器链中注册一个,要禁用它,你需要添加一个FilterRegistrationBean来禁用它。

@Bean
public FilterRegistrationBean<AppPreAuthenticatedProcessingFilter> preAuthenticationFilterRegistrationBean(AppPreAuthenticatedProcessingFilter filter) {
  FilterRegistrationBean<AppPreAuthenticatedProcessingFilter> frb = new FilterRegistrationBean<>(filter);
  frb.setEnabled(false);
  return frb;
}
于 2021-03-25T13:17:34.567 回答