title: Spring Security AnonymousAuthFilter With PreAuthenticationFilter Allowing Unauthorized Requests
body: <p>I have a fairly simplistic Spring Security configuration in my Spring MVC web app.  I am receiving REST requests from a remote web application that get authenticated through my preauth filter.  I simply look for a header in the request, and if present, I return that String value (which is the username) as the authentication object.  This works fine and when a request comes in, the user gets authenticated.</p>
  
  <p>For whatever reason, any time I attempt to enforce a pattern-based security antMatcher or controller method annotated security, it results in the client getting a CORS error.  I have to keep the access fully open to allow the actual request to take place in this cross-domain environment.</p>
  
  <p>My issue is, after a while, the session seems to expire.  When a user hits one of my controllers and I try to get the username from the Principal object, I get a NullPointerException because the Principal is null.  Once it expires, it looks like the AnonymousAuthFilter kicks in and just lets the user connect as anonymous.</p>
  
  <p>I'm assuming I don't want a completely stateless authentication session, because I'm also using the session for websockets, and when I use my messaging template to "convertAndSendToUser", I need to provide the username and Spring needs to lookup the websocket session.  However, I would like to force the security chain to recognize if the incoming request does not have a principal assigned, to force the request back through my PreAuthFilter and re-establish the session.</p>
  
  <p>Is this possible?</p>
  
  <p>Here is a quick rundown of my configure method in my security config file:</p>
  
  <pre><code>@Override
      protected void configure(HttpSecurity http) throws Exception {
          // Create authentication providers and authentication manager
          List&lt;AuthenticationProvider&gt; authenticationProviders = new ArrayList&lt;&gt;(1);
          AuthenticationProvider authProvider = preAuthenticatedAuthenticationProvider();
          authenticationProviders.add(authProvider);
          AuthenticationManager authenticationManager = authenticationManager(authenticationProviders);
  
          // Create the pre-authentication filter
          MyPreAuthFilter myPreAuthFilter = myPreAuthFilter(authenticationManager);
          myPreAuthFilter.setAuthenticationManager(authenticationManager);
  
          // configure http security
          http
                  .csrf().disable()
                  .headers().addHeaderWriter(new XFrameOptionsHeaderWriter(XFrameOptionsHeaderWriter.XFrameOptionsMode.SAMEORIGIN))
                  .and()
                  .authenticationProvider(authProvider)
                  .addFilter(myPreAuthFilter)
                  .authorizeRequests()
                  .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
                  .antMatchers("/stomp/**").permitAll()
                  .antMatchers("/**").permitAll();
      }
  </code></pre>
  
  <p>UPDATE:  So I just learned about this method on the http object:  </p>
  
  <pre><code>.anonymous().disable()
  </code></pre>
  
  <p>However, when I use that, all my CORS requests fail again.  I think the issue is specifically the preflight OPTIONS requests.  This can't be authenticated -- it needs to be anonymously accessible.  So I think to get the behavior I want out of my cross-domain authentication, I need to disable the anonymous filter, but doing so breaks one of the key tenants of being able to perform cross-domain requests.  Ugh.  Anybody know how to disable anonymous for all requests besides OPTIONS?</p>