Spring Security OAuth 2.0, POST /oauth/token 요청 분석

기능

  • POST /oauth/token 요청은 클라이언트에게 access_token을 발급하는 기능을 한다.

  • 발급된 access_token의 만료일시는 연장되지 않는다. 만료되면 재사용이 불가능하다. 만료일시가 다가올 경우 grant_type = refresh_token 파라메터를 요청하면 access_token이 새로 발급된다.

실행조건

  • grant_typeauthorization_code일 경우 GET /oauth/authorize 요청에 따라 사용자가 로그인 및 권한 위임 동의에 완료하여 redirect_uri를 통해 code 파라메터를 받은 상태이어야 한다. 더 정확히 기술하자면 code 파라메터를 받은지 몇 분 내의 시간이어야 한다.

요청사양

### grant_type = 'authorization_code'
curl -X POST \
'http://localhost:8080/oauth/token' \
-U 'some_client_id:some_client_secret' \
-d 'grant_type=authorization_code' \
-d 'code=DO8jTT' \
-d 'redirect_uri=http://localhost'

### grant_type = 'client_credentials'
curl -X POST \ 'http://localhost:8080/oauth/token' \ 
-U 'some_client_id:some_client_secret' \ 
-d 'grant_type=client_credentials'

### grant_type = 'refresh_token'
curl -X POST \ 'http://localhost:8080/oauth/token' \
-U 'some_client_id:some_client_secret' \
-d 'grant_type=refresh_token' \
-d 'refresh_token=9c2d4115-ebd2-4ff5-8f69-1c2e1198cf52'
  • client_id, client_secret 파라메터는 Basic Auth 방식으로 삽입되어야 한다.

  • 저장된 code 값은 기본적으로 RandomValueAuthorizationCodeServices 구현체(기본 구현체는 InMemoryAuthorizationCodeServices)의 remove(code)로 확인한다.

  • code 파라메터가 유효하지 않을 경우(이미 응답하여 삭제됬거나, 발급된 적이 없는 값일 경우) InvalidGrantException 예외를 발생시킨다.

  • 요청 파라메터의 redirect_uri가 저장된 것과 일치하지 않을 경우 RedirectMismatchException 예외를 발생시킨다.

  • grant_type 파라메터가 유효하지 않을 경우 UnsupportedGrantTypeException 예외를 발생시킨다.

  • access_token의 생성은 DefaultTokenServices 구현체의 createAccessToken(authentication)이 수행한다.

  • access_token과 맵핑될 키는 DefaultAuthenticationKeyGenerator 구현체의 generateKey(values)가 수행하는데 권한 위임에 동의한 사용자의 username, 요청 클라이언트의 client_id, 사용자가 동의한 scope 문자열을 조합한 후 MD5 해시 값으로 변환하여 얻어낸다. (ex: 8a0fd26d6c5771a5b739ea915262ea8c)

  • 실제 access_tokenUUID.randomUUID().toString()로 생성한다.

응답사양

# 성공 응답
{
    "access_token": "a1849c64-2ca6-4d32-8f15-6cf01029dfb6",
    "token_type": "bearer",
    "refresh_token": "9c2d4115-ebd2-4ff5-8f69-1c2e1198cf52",
    "expires_in": 43199,
    "scope": "read:users"
}

# code 파라메터가 유효하지 않을 경우
{
    "error": "invalid_grant",
    "error_description": "Invalid authorization code: DO8jTT"
}

# redirect_uri 파라메터가 유효하지 않을 경우
{
    "error": "invalid_grant",
    "error_description": "Redirect URI mismatch."
}

# authorization_code 파라메터가 유효하지 않을 경우
{
    "error": "unsupported_grant_type",
    "error_description": "Unsupported grant type: authorization_code"
}
  • 앞서 @EnableAuthorizationServer 클래스 작성시 clients.authorizedGrantTypes(“authorization_code”, “refresh_token”)와 같이 클라이언트에게 허가된 grant_type으로 refresh_token을 명시하면 응답에 refresh_token 또한 같이 내려온다.
저작자 표시 비영리 동일 조건 변경 허락
신고