title: Spring Boot 2 - 403 instead of 401 in filter-based JWT Spring Security implementation
body: <p>I'm trying to make my Spring Boot 1.5.x REST API project 2.x.x-compatible, without breaking lots of code. I'm stuck in a filter-based JWT Spring Security implementation I used to use:</p>
  
  <p>In order to authenticate credentials through "/login" endpoint, I used to extend <code>UsernamePasswordAuthenticationFilter</code> as follows:</p>
  
  <pre><code>public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
  
      private AuthenticationManager authenticationManager;
  
      private JWTUtil jwtUtil;
  
      public JWTAuthenticationFilter(AuthenticationManager authenticationManager, JWTUtil jwtUtil) {
          this.authenticationManager = authenticationManager;
          this.jwtUtil = jwtUtil;
      }
  
      @Override
      public Authentication attemptAuthentication(HttpServletRequest req,
                                                  HttpServletResponse res) throws AuthenticationException {
  
          try {
              CredenciaisDTO creds = new ObjectMapper().readValue(req.getInputStream(), CredenciaisDTO.class);
              UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(creds.getEmail(), creds.getSenha(), new ArrayList&lt;&gt;());
              Authentication auth = authenticationManager.authenticate(authToken);
              return auth;
          }
          catch (IOException e) {
              throw new RuntimeException(e);
          }
      }
  
      @Override
      protected void successfulAuthentication(HttpServletRequest req,
                                              HttpServletResponse res,
                                              FilterChain chain,
                                              Authentication auth) throws IOException, ServletException {
          String username = ((UserSS) auth.getPrincipal()).getUsername();
          String token = jwtUtil.generateToken(username);
          res.addHeader("Authorization", "Bearer " + token);
          res.addHeader("access-control-expose-headers", "Authorization");
      }
  }
  </code></pre>
  
  <p>Also, in order to authorize beared-token requests, I used to extend <code>BasicAuthenticationFilter</code> as follows:</p>
  
  <pre><code>public class JWTAuthorizationFilter extends BasicAuthenticationFilter {
  
      private JWTUtil jwtUtil;
  
      private UserDetailsService userDetailsService;
  
      public JWTAuthorizationFilter(AuthenticationManager authenticationManager, JWTUtil jwtUtil, UserDetailsService userDetailsService) {
          super(authenticationManager);
          this.jwtUtil = jwtUtil;
          this.userDetailsService = userDetailsService;
      }
  
      @Override
      protected void doFilterInternal(HttpServletRequest request,
                                      HttpServletResponse response,
                                      FilterChain chain) throws IOException, ServletException {
  
          String header = request.getHeader("Authorization");
          if (header != null &amp;&amp; header.startsWith("Bearer ")) {
              UsernamePasswordAuthenticationToken auth = getAuthentication(header.substring(7));
              if (auth != null) {
                  SecurityContextHolder.getContext().setAuthentication(auth);
              }
          }
          chain.doFilter(request, response);
      }
  
      private UsernamePasswordAuthenticationToken getAuthentication(String token) {
          if (jwtUtil.isValid(token)) {
              String username = jwtUtil.getUsername(token);
              UserDetails user = userDetailsService.loadUserByUsername(username);
              return new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
          }
          return null;
      }
  }
  </code></pre>
  
  <p>Everything worked as expected:</p>
  
  <ul>
  <li><p>Requests to /login with bad credentials used to return 401 with a
  standand "Unauthorized/Authentication failed: bad credentials" object.</p></li>
  <li><p>Beared-token requests not authorized by <code>BasicAuthenticationFilter</code>
  used to return 403 with a standard "Forbidden/Access denied" object.</p></li>
  </ul>
  
  <p>However, if I use that code in a Spring Boot 2.0.0 project, requests do /login were returning 403 with empty-body response. </p>
  
  <p><a href="https://stackoverflow.com/questions/49241384/401-instead-of-403-with-spring-boot-2">This</a> post adviced to include <code>http.exceptionHandling().authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED));</code> in <code>configure</code> method from the security configuration class. That way I could get 401 for /login requests, but it's still returning an empty-body response (instead of that standard "Unauthorized" error object). Besides, now all requests not authorized by <code>BasicAuthenticationFilter</code> are also returning 401 with empty-body response (while the correct should be returning 403 with that standard "Forbidden" error object inside body). </p>
  
  <p>How can I get back that desirable behavior I had before?  </p>