2017-03-29 1 views
1

html 로그인 폼을 반환하는 대신 사용자가 로그인하지 않은 경우 json 응답을 반환하는 데 어려움을 겪고 있습니다.스프링 부트 OAUTH2에서 로그인 폼 대신 RESTful/json 응답을 반환합니다.

응용 프로그램은 @ RestController 's 만 사용하며 어떤 웹 지원도 원하지 않습니다. 나는 브라우저 또는 우편 배달부를 사용하여 가져 오기 요청을 수행 할 때

http 
     .authorizeRequests() 
       .anyRequest().authenticated() 
       .and() 
       .formLogin() 
       .and() 
       .httpBasic().disable(); 

, 나는 기본 스프링 HTML 로그인 양식을 다시받을 수 있습니다.

security.basic.enabled=true 

나는 OATH2를 사용하고, 나는 토큰을 요청할 때 잘 작동하고 나는이 같은 응답을 얻을 :

: 어떻게 든

{ 
    "access_token": "227803d1-fe94-4e31-b496-3a03bafb9479", 
    "token_type": "bearer", 
    "refresh_token": "322f4ee9-4c48-4e06-a129-f4b6af93d664", 
    "expires_in": 43199, 
    "scope": "read write" 
} 

, 그것은이 예에서 올바른 작동 https://github.com/royclarkson/spring-rest-service-oauth

그리고 내가 권한이 없습니다있을 때, 내가 다시 이런 걸 원하는 :

,536,913,632을 10
{ 
    "error": "unauthorized", 
    "error_description": "An Authentication object was not found in the SecurityContext" 
} 

하지만 로그인 양식이 표시되는데 위 응답을 원합니다. 내가 도대체 ​​뭘 잘못하고있는 겁니까? 나는 왜 GitHub 예제에서 작동하는지, 그리고 내 경우에는 그렇지 않은지를 알 수 없다. 로그인 양식을 완전히 비활성화하고 json 응답을 강제 적용하는 방법이 있습니까?

+0

은 왜 당신이 당신의 설정에'.formLogin을()'추가? – chaoluo

+0

하지 않고도 – Kramer

답변

1

AuthenticationEntryPoint은 봄 보안의 예외 처리에 사용됩니다. 당신이 당신의 인증을 위해 기본을 사용하는 경우 당신은 당신의 치어에 OAuth2를, 당신은 당신의 엔트리 포인트에 대한 OAuth2AuthenticationEntryPoint을 사용할 수 있습니다 추가 한 경우

, 엔트리 포인트는 봄 보안 예외 처리를위한 것입니다, 당신은이

처럼 config (설정) 할 수 있습니다 당신이 그것을 위해 OAuth2Exception, AuthenticationException, AccessDeniedException를 얻기 위해 노력할 것입니다 예외가 OAuth2AuthenticationEntryPoint

// Try to extract a SpringSecurityException from the stacktrace 
    Throwable[] causeChain = throwableAnalyzer.determineCauseChain(e); 
    Exception ase = (OAuth2Exception) throwableAnalyzer.getFirstThrowableOfType(
      OAuth2Exception.class, causeChain); 

    if (ase != null) { 
     return handleOAuth2Exception((OAuth2Exception) ase); 
    } 

    ase = (AuthenticationException) throwableAnalyzer.getFirstThrowableOfType(AuthenticationException.class, 
      causeChain); 
    if (ase != null) { 
     return handleOAuth2Exception(new UnauthorizedException(e.getMessage(), e)); 
    } 

    ase = (AccessDeniedException) throwableAnalyzer 
      .getFirstThrowableOfType(AccessDeniedException.class, causeChain); 
    if (ase instanceof AccessDeniedException) { 
     return handleOAuth2Exception(new ForbiddenException(ase.getMessage(), ase)); 
    } 

    ase = (HttpRequestMethodNotSupportedException) throwableAnalyzer 
      .getFirstThrowableOfType(HttpRequestMethodNotSupportedException.class, causeChain); 
    if (ase instanceof HttpRequestMethodNotSupportedException) { 
     return handleOAuth2Exception(new MethodNotAllowed(ase.getMessage(), ase)); 
    } 

    return handleOAuth2Exception(new ServerErrorException(e.getMessage(), e)); 

에서 처리 볼 수

http 
    .httpBasic().authenticationEntryPoint(getCustomerEntryPoint()); 

@Bean 
protected AuthenticationEntryPoint getCustomerEntryPoint() { 
    return new OAuth2AuthenticationEntryPoint(); 
} 

, 나는 당신이 사용할 수있을 것 같아요 .

그리고 당신은 또한 ExceptionTranslationFilter을 config (설정) 할 수있다,이 필터는 봄 보안 체인이며, 잡아 AuthenticationException, AccessDeniedException처럼, 그 후, 예외 핸들러하고 주요 진입 점이며 대부분의 인증을 위해 도움이 될 것입니다 메소드 (예 : FormLogin). 당신이 봄으로 OAuth2를 사용하지 않는 경우

http 
    .exceptionHandling().authenticationEntryPoint(getCustomerEntryPoint()); 

, 지금 당신은 AuthenticationEntryPoint 이해, 그래서 당신은 또한 당신이 AuthenticationEntryPoint 및 사용자 정의

같은 단지 commence 방법 overrider 당신의 예외 응답,

BasicAuthenticationEntryPoint을 소유 구현할 수 있습니다 그것을 'WWW 인증'헤더 LoginUrlAuthenticationEntryPoint를 반환합니다 : 더 authentcation

0

사용자 정의 AuthenticationEntryPoint을 필요로하지 않으며 commence() 우선합니다 때 URL을 대상으로 리디렉션합니다 방법.

사실, 진입 점은 봄 보안 설정에 등록해야합니다

http.exceptionHandling() 
       .authenticationEntryPoint(restAuthenticationEntryPoint) 

샘플 코드 :

public class UserAuthenticationEntryPoint implements 
     AuthenticationEntryPoint { 

    @Override 
    public void commence(HttpServletRequest request, 
      HttpServletResponse response, AuthenticationException ex) 
      throws IOException, ServletException { 
     response.setContentType("application/json"); 
     response.getOutputStream().print("{\"error\":\"Unauthorized.. Please authenticate..\"}"); 
     response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); 
    } 
} 
관련 문제