2016-05-16 10 views
0

Ich habe einige tokenbasierte Authentifizierung in meiner spring-boot Anwendung implementiert. Ich habe einen Filter und in diesem Filter, ich tue dem folgend:Ausnahmebedingung beim Authentifizierungsfehler

@Override 
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 
    HttpServletRequest httpRequest = (HttpServletRequest) request; 
    String authToken = httpRequest.getHeader("X-TOKEN-AUTH"); 
    String username = null; 

    if (securityEnabled) { 
     if (authToken != null) { 

      try { 
       username = userTokenService.validateToken(authToken); 
       UserDetails userDetails = userDetailsService.loadUserByUsername(username); 
       UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(userDetails.getUsername(), null, userDetails.getAuthorities()); 
       auth.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpRequest)); 
       SecurityContextHolder.getContext().setAuthentication(auth); 

      } catch (AuthenticationException ae) { 
       //TODO log something about signature exception 
       log.warn(ae.getMessage()); 
      } 
     } 

    } 

    chain.doFilter(request, response); 
} 

Ich habe auch einen benutzerdefinierten AuthFailureHandler:

@Component 
public class AuthFailureHandler extends SimpleUrlAuthenticationFailureHandler { 
    @Override 
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, 
             AuthenticationException exception) throws IOException, ServletException { 
     response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); 

     PrintWriter writer = response.getWriter(); 
     writer.write(exception.getMessage()); 
     writer.flush(); 
    } 
} 

Meinen Code username = userTokenService.validateToken(authToken); ein AuthenticationException aus verschiedenen Gründen werfen. AuthenticationException ist eine benutzerdefinierte Ausnahme, die Exception erweitert. Als ich diese Ausnahme abfangen, möchte ich noch einen 401 zurück, aber ich möchte, dass meine Nachricht in erscheinen, was derzeit von Spring Security als Standard zurück als JSON gesendet werden:

{ 
    "timestamp": 1463408604943, 
    "status": 401, 
    "error": "Unauthorized", 
    "message": "An Authentication object was not found in the SecurityContext", 
    "path": "/api/brands/2" 
} 

Ich möchte, zum Beispiel .. .

{ 
    "timestamp": 1463408604943, 
    "status": 401, 
    "error": "Unauthorized", 
    "message": "Invalid Token: Expired", 
    "path": "/api/brands/2" 
} 

Ich bin mir nicht sicher, wie dieses Verhalten überschrieben werden kann.

+0

Diese 'AuthenticationException' ist Ihre benutzerdefinierte Ausnahme oder die' AuthenticationException' im Frühling? –

+0

Es ist meine eigene benutzerdefinierte Ausnahmeklasse – Gregg

Antwort

0

Also ... habe ich endlich herausgefunden. Das Problem war, dass Filter in der Nahrungskette höher sind, so dass Spring nicht wirklich viel mit einbezieht. Wo ich eine Ausnahme im Filter geworfen habe, hat Spring sie nicht unbedingt eingefangen. Der Filter würde einfach eine 500 auslösen und die Ausnahmemeldung anzeigen. Um es zu beheben, musste ich einfach meine Ausnahmen im Filter abfangen und dann sendError mit dem entsprechenden http-Status anrufen.

try { 
    username = userTokenService.validateToken(authToken); 
    UserDetails userDetails = userDetailsService.loadUserByUsername(username); 
    UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(userDetails.getUsername(), null, userDetails.getAuthorities()); 
    auth.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpRequest)); 
    SecurityContextHolder.getContext().setAuthentication(auth); 
    chain.doFilter(request, response); 
    return; 
} catch (Exception ex) { 
    httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, ex.getMessage()); 
    return; 
} 

Die return Anweisung in den catch ist so, dass mein chain.doFilter(request, response); am Ende der doFilter Methode wird nicht aufgerufen.

Verwandte Themen