title: Spring Boot Security does not throw 401 Unauthorized Exception but 404 Not Found
body: <p>My authentication is based on a <a href="https://github.com/FutureProcessing/spring-boot-security-example/blob/master/src/main/java/com/futureprocessing/spring/infrastructure/security/AuthenticationFilter.java">spring-boot-security-example</a>.
  When I enter an invalid token, I would like to throw a 401 Unauthorized exception. However, I always get a 404 resource not found instead. My configuration sets an exception handling but it is ignored - probably because my AuthenticationFilter is added before and the request does not reach my exception handler.</p>
  
  <p>What would I need to change to throw 401 exceptions instead?</p>
  
  <p>I have a authentication filter:</p>
  
  <pre><code>public class AuthenticationFilter extends GenericFilterBean {
  
  ...
  
  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
      HttpServletRequest httpRequest = asHttp(request);
      HttpServletResponse httpResponse = asHttp(response);
      Optional&lt;String&gt; token = Optional.fromNullable(httpRequest.getHeader("X-Auth-Token"));
  
      try {
          if (token.isPresent()) {
              logger.debug("Trying to authenticate user by X-Auth-Token method. Token: {}", token);
              processTokenAuthentication(token);
              addSessionContextToLogging();
          }
  
          logger.debug("AuthenticationFilter is passing request down the filter chain");
          chain.doFilter(request, response);
      } catch (InternalAuthenticationServiceException internalAuthenticationServiceException) {
          SecurityContextHolder.clearContext();
          logger.error("Internal authentication service exception", internalAuthenticationServiceException);
          httpResponse.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
      } catch (AuthenticationException authenticationException) {
          SecurityContextHolder.clearContext();
          httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, authenticationException.getMessage());
      } finally {
          MDC.remove(TOKEN_SESSION_KEY);
          MDC.remove(USER_SESSION_KEY);
      }
  }
  
  private void addSessionContextToLogging() {
      ...
  }
  
  ...
  
  private void processTokenAuthentication(Optional&lt;String&gt; token) {
      Authentication resultOfAuthentication = tryToAuthenticateWithToken(token);
      SecurityContextHolder.getContext().setAuthentication(resultOfAuthentication);
  }
  
  private Authentication tryToAuthenticateWithToken(Optional&lt;String&gt; token) {
      PreAuthenticatedAuthenticationToken requestAuthentication = new PreAuthenticatedAuthenticationToken(token, null);
      return tryToAuthenticate(requestAuthentication);
  }
  
  private Authentication tryToAuthenticate(Authentication requestAuthentication) {
      Authentication responseAuthentication = authenticationManager.authenticate(requestAuthentication);
      if (responseAuthentication == null || !responseAuthentication.isAuthenticated()) {
          throw new InternalAuthenticationServiceException("Unable to authenticate Domain User for provided credentials");
      }
      logger.debug("User successfully authenticated");
      return responseAuthentication;
  }
  </code></pre>
  
  <p>a AuthenticationProvider implementation:</p>
  
  <pre><code>@Provider
  public class TokenAuthenticationProvider implements AuthenticationProvider {
  
  @Override
  public Authentication authenticate(Authentication authentication) throws AuthenticationException {
      Optional&lt;String&gt; token = (Optional) authentication.getPrincipal();
      if (!token.isPresent() || token.get().isEmpty()) {
          throw new BadCredentialsException("No token set.");
      }
      if (!myCheckHere()){
          throw new BadCredentialsException("Invalid token");
      }
  
      return new PreAuthenticatedAuthenticationToken(myConsumerObject, null, AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_API_USER"));
  }
  
  ...
  
  }
  </code></pre>
  
  <p>and a configuration which looks as follows:</p>
  
  <pre><code>@Configuration
  @EnableWebSecurity
  @EnableGlobalMethodSecurity(prePostEnabled = true)
  public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
  
  @Override
  protected void configure(HttpSecurity http) throws Exception {
      http.
              csrf().disable().
              sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).
              and().
              anonymous().disable().
              exceptionHandling().authenticationEntryPoint(unauthorizedEntryPoint());
  
      http.addFilterBefore(new AuthenticationFilter(authenticationManager()), BasicAuthenticationFilter.class);
  }
  
  
  @Override
  protected void configure(AuthenticationManagerBuilder auth) throws Exception {
      auth.authenticationProvider(tokenAuthenticationProvider());
  }
  
  
  @Bean
  public AuthenticationProvider tokenAuthenticationProvider() {
      return new TokenAuthenticationProvider();
  }
  
  @Bean
  public AuthenticationEntryPoint unauthorizedEntryPoint() {
      return (request, response, authException) -&gt; response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
  }
  }
  </code></pre>