2016-05-16 11 views
0

spring-bootアプリケーションでトークンベースの認証を実装しました。私は、フィルタを持っており、そのフィルタでは、私は次のことをやっている:認証に失敗した場合のスロー例外

@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); 
} 

私はまた、カスタム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(); 
    } 
} 

私のコードusername = userTokenService.validateToken(authToken);は、様々な理由のためにAuthenticationExceptionをスローします。 AuthenticationExceptionは、Exceptionを拡張するカスタム例外です。私はこの例外をキャッチしたとき、私はまだ401を返すようにしたいが、私は私のメッセージは、現在デフォルトとしてSpring SecurityでJSONとして送り返されているものに表示する:

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

私は、たとえば、たいと思います...

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

この動作を無効にする方法は不明です。

+0

この 'AuthenticationException'は、あなたのカスタム例外かSpringの' AuthenticationException'ですか? –

+0

自分のカスタム例外クラスです – Gregg

答えて

0

だから私はついにこれを理解しました。問題は、フィルターが食物連鎖の上にあるため、実際にはそれほど多くの春に関わらないということでした。フィルタで例外をスローしていたところで、Springは必ずしもそれをキャッチしていませんでした。フィルタは500を投げて例外メッセージを表示します。これを修正するには、フィルタで例外をキャッチして、適切なhttpステータスのsendErrorを呼び出すだけでした。

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; 
} 

chain.doFilter(request, response);doFilter方法の終わりには呼び出されないようにcatchreturn文があります。

関連する問題