title: Spring Boot Security PreAuthenticated Scenario with Anonymous access
body: <p>I have a Spring Boot (1.5.6) application that is using the "<a href="https://docs.spring.io/spring-security/site/docs/current/reference/html/preauth.html" rel="nofollow noreferrer">pre-authenticated</a>" authentication scenario (SiteMinder) from Spring Security.</p>
  
  <p>I have a need to expose the actuator "health" endpoint anonymously meaning the requests to that endpoint will <strong>not</strong> go through SiteMinder and as a result, the SM_USER header will not be present in the HTTP Request Header.</p>
  
  <p>The problem I'm facing is that no matter how I try to configure the "health" endpoint, the framework is throwing an <code>org.springframework.security.web.authentication.preauth.PreAuthenticatedCredentialsNotFoundException</code> because the expected header ("SM_USER") is not present when the request does not go through SiteMinder.</p>
  
  <p>This was my original security config:</p>
  
  <pre><code>@Configuration
  @EnableWebSecurity
  public class SecurityConfig extends WebSecurityConfigurerAdapter {
  
      @Override
      protected void configure(HttpSecurity http) throws Exception {
  
          http
              .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
              .and()
                  .authorizeRequests().antMatchers("/cars/**", "/dealers/**")
                  .hasAnyRole("CLIENT", "ADMIN")
              .and()
                  .authorizeRequests().antMatchers("/health")
                  .permitAll()
              .and()
                  .authorizeRequests().anyRequest().denyAll()
              .and()
                  .addFilter(requestHeaderAuthenticationFilter())
                  .csrf().disable();
      }
  
      @Bean
      public Filter requestHeaderAuthenticationFilter() throws Exception {
          RequestHeaderAuthenticationFilter filter = new RequestHeaderAuthenticationFilter();
          filter.setAuthenticationManager(authenticationManager());
          return filter;
      }
  
      @Override
      public void configure(AuthenticationManagerBuilder auth) throws Exception {
          auth.authenticationProvider(preAuthProvider());
      }
  
      @Bean
      public AuthenticationProvider preAuthProvider() {
          PreAuthenticatedAuthenticationProvider authManager = new PreAuthenticatedAuthenticationProvider();
          authManager.setPreAuthenticatedUserDetailsService(preAuthUserDetailsService());
          return authManager;
      }
  
      @Bean
      public AuthenticationUserDetailsService&lt;PreAuthenticatedAuthenticationToken&gt; preAuthUserDetailsService() {
          return new UserDetailsByNameServiceWrapper&lt;&gt;(inMemoryUserDetails());
      }
  
      @Bean
      public UserDetailsService inMemoryUserDetails() {
          return new InMemoryUserDetailsManager(getUserSource().getUsers());
      }
  
      @Bean
      public UserHolder getUserHolder() {
          return new UserHolderSpringSecurityImple();
      }
  
      @Bean
      @ConfigurationProperties
      public UserSource getUserSource() {
          return new UserSource();
      }
  </code></pre>
  
  <p>I've tried to exclude the /health endpoint a couple different ways to no avail.</p>
  
  <p>Things I've tried:</p>
  
  <p>Configure health endpoint for anonymous access rather than permitAll:</p>
  
  <pre><code>http
     .authorizeRequests().antMatchers("/health")
     .anonymous()
  </code></pre>
  
  <p>Configure WebSecurity to ignore the health endpoint:</p>
  
  <pre><code>@Override
  public void configure(WebSecurity web) throws Exception {
      web.ignoring().antMatchers("/health");
  }
  </code></pre>
  
  <p>Turn off security for <em>all</em> actuator endpoints (not idea but I was grasping for straws):</p>
  
  <pre><code>management.security.enabled=false
  </code></pre>
  
  <p>Looking at the logs, the problem seems to be that the RequestHeaderAuthenticationFilter is getting registered as a <strong>top level</strong> filter rather than a filter in the existing <strong>securityFilterChain</strong>:</p>
  
  <pre><code>.s.DelegatingFilterProxyRegistrationBean : Mapping filter: 'springSecurityFilterChain' to: [/*]
  o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'webRequestLoggingFilter' to: [/*]
  o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'requestHeaderAuthenticationFilter' to: [/*]
  </code></pre>
  
  <p>Based on my understanding, because the <code>RequestHeaderAuthenticationFilter</code> extends <code>AbstractPreAuthenticatedProcessingFilter</code>, the framework knows where to insert the filter within the chain which is why I'm not tinkering with the addFilter<strong>Before</strong> or addFilter<strong>After</strong> variants.  Maybe I should be?  Does anybody know the correct place to insert the filter explicitly? (I thought the need for explicitly specifying filter order was removed in prior versions of Spring Security)</p>
  
  <p>I know I can configure the <code>RequestHeaderAuthenticationFilter</code> so that it doesn't throw an exception if the header is not present but I'd like to keep that on if at all possible.</p>
  
  <p>I found this SO post that seems to be similar to my problem but unfortunately there's no answer there either.
  <a href="https://stackoverflow.com/questions/45971407/spring-boot-security-preauthentication-with-permitted-resources-still-authenti">spring-boot-security-preauthentication-with-permitted-resources-still-authenti</a></p>
  
  <p>Any help would be greatly appreciated!
  Thanks!</p>