title: How to handle exceptions properly in custom Spring security 3.0 authentication?
body: <p>I'm developing a REST service based in tokens. When an user goes to ../rest/authenticate with the user and password via curl, gets a valid token in order to use the whole API.</p>
  
  <p>My problem appears when the user forgets to insert the username, the password or the token in the other methods because i've not managed to handle the Authentication exceptions as I want.</p>
  
  <p>I cand handle the exceptions but tomcat gets the response and inserts some html that I don't expect.</p>
  
  <p><img src="https://i.stack.imgur.com/RTmEC.jpg" alt="curl"></p>
  
  <p>This is the typical response of tomcat.
  <img src="https://i.stack.imgur.com/LEcha.jpg" alt="tomcat"></p>
  
  <p>Is it possible to receive a response like 200 OK which don't have this html code?</p>
  
  <p>At the momment, this is my config:</p>
  
  <h1>AuthenticationProcessingFilter</h1>
  
  <p>Decides if the url is secured or not. If has to be secured, calls the authentication manager in order to validate it. If receives an authentication exceptions calls the AuthenticationEntryPoint</p>
  
  <pre><code>public class AuthenticationTokenProcessingFilter extends GenericFilterBean {
  
      private final Collection&lt;String&gt; nonTokenAuthUrls = Lists.newArrayList("/rest","/rest/authenticate");
  
      TokenAuthenticationManager tokenAuthenticationManager;
      RestAuthenticationEntryPoint restAuthenticationEntryPoint;
  
      public AuthenticationTokenProcessingFilter(TokenAuthenticationManager tokenAuthenticationManager, RestAuthenticationEntryPoint restAuthenticationEntryPoint) {
          this.tokenAuthenticationManager = tokenAuthenticationManager;
          this.restAuthenticationEntryPoint = restAuthenticationEntryPoint;
      }
  
      @Override
      public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
          HttpServletRequest httpRequest = (HttpServletRequest)request;
          HttpServletResponse httpResponse = (HttpServletResponse)response;
          try{
              if(!nonTokenAuthUrls.contains(httpRequest.getRequestURI())){ //Auth by token
                   String hash = httpRequest.getHeader("token");
                   UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(hash, null);
                   authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails((HttpServletRequest) request));
                   SecurityContextHolder.getContext().setAuthentication(tokenAuthenticationManager.authenticate(authentication));
              }
              response.reset();
              chain.doFilter(request, response); 
          }catch(AuthenticationException authenticationException){
              SecurityContextHolder.clearContext();
              restAuthenticationEntryPoint.commence(httpRequest, httpResponse, authenticationException);
          }
      }
  </code></pre>
  
  <h1>AuthenticationManager</h1>
  
  <pre><code>public class TokenAuthenticationManager implements AuthenticationManager{
  
      @Autowired
      UserService userService;
  
      @Autowired
      TokenService tokenService;
  
      @Override
      public Authentication authenticate(Authentication authentication) throws AuthenticationException {
          Object hash = authentication.getPrincipal();
          if(hash == null)
              throw new BadCredentialsException("Token is required");
          User user = tokenService.getUserFromTokenHash((String)hash); 
          if(user == null)
              throw new BadCredentialsException("Non-existent token");
          if(!tokenService.validate((String)hash)) 
              throw new BadCredentialsException("Expired Token");
          org.springframework.security.core.userdetails.User userDetails = new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), getUserGrantedAuthorities(user.getRoles()));
          return new UsernamePasswordAuthenticationToken(userDetails, user.getPassword(), getUserGrantedAuthorities(user.getRoles()));
      }
  </code></pre>
  
  <h1>AuthenticationEntryPoint</h1>
  
  <p>This class works OK. The code received is 401 unauthorized but the message is in the tomcat html</p>
  
  <p>public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint {</p>
  
  <pre><code>@Override
  public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authenticationException) throws IOException, ServletException {
      response.setContentType("application/json");
      response.sendError( HttpServletResponse.SC_UNAUTHORIZED, authenticationException.getMessage() );
      response.getOutputStream().println("{ \"error\": \"" + authenticationException.getMessage() + "\" }");
  }
  </code></pre>
  
  <p>}</p>
  
  <p>The RestAccessDeniedHanler is not called either. It's difficult becasue there are a lot of classes that have to be implemented.</p>
  
  <p>I reviewed some post in stackoverflow and other websites and my approach consist on catching the exceptions in the AuthenticationProcessingFilter and call the AuthenticationEntryPoint manually. I decided to do that becasue I've tried to configure this in the applicationContext-security.xml with no success.</p>
  
  <h1>appliacionContext-security.xml</h1>
  
  <pre><code>&lt;b:bean id="restAuthenticationEntryPoint" class="...web.security.RestAuthenticationEntryPoint" /&gt; 
  
  &lt;b:bean id="tokenAuthenticationManager" class="...dp.web.security.TokenAuthenticationManager"/&gt;
  
  &lt;b:bean id="AuthenticationTokenProcessingFilter" class="...web.security.AuthenticationTokenProcessingFilter"&gt;
      &lt;b:constructor-arg type="...dp.web.security.TokenAuthenticationManager" ref="tokenAuthenticationManager"&gt;&lt;/b:constructor-arg&gt;
      &lt;b:constructor-arg type="...dp.web.security.RestAuthenticationEntryPoint" ref="restAuthenticationEntryPoint"&gt;&lt;/b:constructor-arg&gt;
  &lt;/b:bean&gt;
  
  &lt;b:bean id="accessDeniedHandler" class="...dp.web.security.RestAccessDeniedHandler"&gt;
  &lt;/b:bean&gt;
  
  &lt;http realm="Protected REST API" pattern="/rest/**" use-expressions="true" auto-config="false" create-session="stateless"  entry-point-ref="restAuthenticationEntryPoint"&gt;
      &lt;custom-filter ref="AuthenticationTokenProcessingFilter" position="FORM_LOGIN_FILTER" /&gt;
      &lt;access-denied-handler ref="accessDeniedHandler"/&gt;
  &lt;/http&gt; 
  </code></pre>
  
  <p>how can I send a clean response with the error code and a message?</p>