[ SSO ] Grant Type

duck-ach·2023년 9월 14일
0

SSO(Single Sign-On)

목록 보기
1/1

✅ Grant Type이란?

OAuth 2.0 의 핵심은 다양한 Client 환경에 적합한 인증 및 권한의 grant_type(위임 방법)을 제공하고 그 결과로 Client에게 access_token 을 발급하는 것이다.

한 번 획득 된 access_token 은 만료 시점까지 모든 리소스 서버의 엔드포인트 요청 헤더에 authorizatiton : Bearer {ACCESS_TOKEN} 으로 첨부된다.

✅ Grant Type의 종류

사용자의 인증 과정에 개입하는 2가지 방식(authorization code, implicit) 과 사용자가 인증 과정에 개입하지 않는 2가지 방식(client credentials, resource owner password credentials) 이 있다.

마지막으로, 만료된 access_token 을 재발급 받기 위한 refresh_token 이 있다.

authorization code

💡 ‘인가 받은 code값을 토대로 토큰을 요청하는 방식’

토큰(Token) 자체도 인가를 받아서 발행되는 대상인데 토큰을 발행하기 위해 또 한 번의 인가 받은 code값을 필요로 하여 가장 복잡하면서도 가장 많이 쓰이는 방식이다,

복잡한 것은 개발자의 몫이지 사용자들(고객)의 입장에선 신경 쓸 필요가 없기 때문이다. (복잡할 수록 공격 방어, 노출의 위험도 방지)

authorization code의 인증/인가 Flow

redirect_uri의 쓰임새?

Token 발행을 요청 받은 Authorization Server는 2가지를 확인한다.

  • #02에서 Client가 전달했던 redirect_uri
  • #04에서 본인이 발급했던 code

OAuth1.0에서 verify 정보의 역할은 해당 Client가 정말 Authorization Server에게 Token발행을 요청했던 그 놈이 맞는 지를 확인하는 역할이었는데, OAuth2.0에서 verify가 사라지면서 redirect_uri가 중간에 다른 누군가 정보를 조작해서 토큰 발행을 요청했을 경우를 막는다.

사용되는 code 값은, 1회성 임을 유의해야 한다.

예를 들어 A라는 Client가 code 값으로 abcdef라는 값을 받아서 해당 값으로 토큰 발행을 요청하려고 했는데, 함께 전달되는 정보(client_id, client_secret, redirect_uri, grant_type)를 잘못 기입해서 틀릴 경우 abcdef라는 코드 값은 즉시 폐기된다. 즉, #02로  돌아가서 진행을 해야 한다는 이야기이다.

implicit

💡 ‘복잡한 거 없이 Client의 토큰 발행의 요청과 동시에 Token 값을 응답해주는 방식’

위의 Autorization Code Grnat Type과 비교했을 때 달라진 점이 딱 3가지 있다.

  • code를 발행하던 flow가 사라짐
  • 최초의 #02 에서 response_type 값이 token으로 바뀜
  • token을 발급해주는 형태가 query string

implicit의 인증/인가 Flow

Implicat Grant Type은 토큰의 값들이 모두 노출이 된다.

Implicit Grant Type은 Client의 요청과 동시에 토큰 값을 응답해준다. → response_type=token

그렇기에 Authorization Server가 Client에게 토큰을 return해주는 방식이 Query String의 형태로 전달된다. → URI에 토큰의 정보가 고스란히 노출되게 되며 심지어 expires_in이라는 만료시기까지 몽땅 노출된다.

Authorization Code Grant Type도 Query String형태로 값을 전달하던데

물론 Authorization Code Grant Type 에서도 위와 같은 Query String 형태로 code값이 노출되긴 하지만, Code는 토큰 발행을 위한 1회성 값이기 때문에 확인 직후 폐기 처리되어 보호할 수 있다.

하지만 Implicit Grant Type 의 Token은 다회성이기 때문에 이후 OAuth Provider뒤에 있는 Resource에게 Expire Time까지 무한정 접근할 수 있게 된다.

그렇다면 Implict는 안 쓰는게 맞을까?

Implict Grant Type 방식은 브라우저에서 자바스크립트와 같은 스크립트 언어로 동작하는 클라이언트들을 지원하기 위한 승인 유형이다. 아래 사항을 만족할 때는 Implict Grant Type 방식을 사용하기 적합합니다.

  • 웹 브라우저의 신뢰도가 높다.
  • 신뢰할 수 없는 사용자나 애플리케이션에 노출될 염려가 적다.
  • 모바일 앱 또는 모바일 단말기에서 동작하는 웹 애플리케이션이다.

client credentials

💡 ‘너무 신뢰가 가는 Client 이기 때문에 Authorization Server가 묻지도 따지지도 않고 토큰을 발행해주는 방식’

대부분의 토큰 발행 유형이 Resource Owner가 시발점이 되는데 비해, 해당 방법은 Client가 주권을 가지고 있다. 타 방법에 비해 허가(Approve)에 대한 동의를 이미 Client가 이미 도장을 찍은 상태라고 볼 수 있다.

즉, 서비스(Client)는 이미 그 자체 만으로도 토큰 발행을 요청할 수 있는 주체가 되어있고, 토큰을 요청 하기만 하면 Authorization Server는 토큰을 발행 해준다.

해당 방법은 사용자의 승인(approval)과정이 생략되어 있기 때문에 Resource Owner와 Client를 하나로 보기도 한다.

client credentials의 인증/인가 Flow

resource owner password credentials

💡 ‘Resource Owner와 Client의 일급기밀(password & secret)을 모아서 토큰 발행을 하는 방식’

해당 방법을 줄여서 Password Credentials라고도 한다.

resource owner password credentials는 바로 위의 Client Credentials와 아주 흡사하다.

다만, 토큰 발행을 요청할 때 추가되는 정보가 있는데 그것이 바로 Resource Owner의 Password이다.

resource owner password credentials의 인증/인가 Flow

ID와 Password를 그냥 서비스(Client)에게 제공한다고?

먼저 Resource Owner가 Client에게 자신의 ID와 Password를 전달하게 되는데 이때 아래와 같은 이유로 보안 위험성이 커지게 됩니다.

  • Resource Owner(Browser) → Client로 ID와 Password가 전해지는 과정에서 누가 중간에 정보를 가로챌 위험이 있음
  • Client가 사용자의 ID와 Password를 알게된다. 예시) 네이버가 아이디와 비밀번호를 모두 노출한 채로 알게된다. 네이버 다니는 친구한테 ‘야, 내 아이디랑 비번 뭐임?’ 물으면 XX에 OO임 하고 즉답을 받을 수 있는 상태가 된다.

토큰 발행 요청 메소드가 GET 방식?

토큰 발행 요청 메소드가 GET방식이라면 Authorization Server에 토큰 발행을 요청할 때에 필요한 정보들이 URI에 고스란히 노출 된다는 의미인데 전달되는 정보들 중에 꽤나 Critical 한 정보들이 많은 것을 확인할 수 있다.

위의 두 가지 위험성 때문에 나온 결론이?

resource owner password credentials Grant Type은 Client에 대한 Resource Owner의 100%를 넘어선 1000%쯤의 신뢰도가 바탕이 될 때 사용하는 것이다.

refresh

💡 ‘Authorization Code Grant Type 또는 Client Credentials Grant Type으로 최초에 인가를 받았을 경우, 발급 되는 Refresh Token으로 Access Token을 재발행 요청하는 Grant Type’

refresh Grant Type은 독립적인 방식은 아니다.

여기서 말하는 Token은 앞서 설명했던 Grant Type들의 Token인 Access Token 과는 다른 Refresh Token 이다.

Refresh Token이 나온 계기

OAuth2.0의 장점은 Token 기반의 인가 방식이지만, 단점도 Token 기반의 인가 방식이다.
즉 Access Token만 있으면 Resource에 누구든 접근을 할 수 있다는 것이며 남의 Access Token을 가지게 되더라도 남의 Resource에 접근을 할 수 있다는 것이다.

즉, Access Token이 탈취된다면 멸망의 길을 걸을 수도 있다는 것이다.

그래서 사용하지 않는 Access Token에 대해서는 파기 시키는 기능은 기본으로 있어야 하며, 이 파기의 주기를 짧게 조절함으로써 행여나 발급 된 Access Token이 탈취 되더라도 근 시간 내에 파기되기 때문에 피해를 줄일 수 있다.

refresh 의 인증/인가 Flow

Client는 기존에 발행 받은 Access Token을 바탕으로 Resource Server에게 Resource를 사용하겠으니 검증을 해 달라고 요청했지만, 이미 해당 토큰은 Expire Time에 의해 파기 되어 Invalid access token 이라는 에러를 리턴 받는다.

사용자(Resource Owner)의 Access Token 이 만료 되었을 때 Client는 어떻게 해야할까?

Client가 사용자(Resource Owner)에게 ‘토큰이 만료 되었으니 재발급 받아’ 하며 안내를 해야 할까요 아니면 알아서 사용자로부터 권한을 위임 받은 만큼 Access Token을 재 요청 해야 할까요?

은행 사이트와 같은 사이트들을 들어갔을 때 로그인 연장을 눌러야 하는 방식처럼 전자의 방식으로 코딩해도 된다. 하지만 이는 사용자의 입장에서는 얼마나 번거로운 프로세스일까?

그래서 나온 것이 Refresh Token인것이다.

Client는 미리 가지고 있던 Refresh Token을 꺼내 들고 Authorization Server에게 Access Token 재 발행을 요청한다.

‘사실 나 아까 인가받은 Client인데 Access Token 좀 다시 발행해줘’

그럼 Authorization Server는 Refresh Token을 체크한 후에 유효한 Access Token을 발행해준다. 그럼 다시 그 시점부터 Access Token의 Expire Time이 흐르게 되는 것이다.

이와같은 방식으로 Access Token의 탈취 시 위험도를 줄이면서 사용자에겐 Resource에 대한 접근 편의성을 제공한다.

Refresh Token은 독립적인 방식이 아니다.

Refresh Grant Type은 독단적으로 토큰을 발행할 수 없다고 앞서 언급했는데, 주재료가 되어 줄 Refresh Token이 있어야 가능하기 때문이다.

이 Refresh Token가 발행되는 시점은 최초의 Access Token이 발행되는 시점이다.

앞서서 설명했던 Grant Type(authorization code, client credentials) 으로 최초의 인가를 받아야만 사용할 수 있는 Grant Type이라는 것이다.

implicit 타입과 resource owner password 타입은 Refresh Token이 발급 되지 않는다.

profile
자몽 허니 블랙티와 아메리카노 사이 그 어딘가

0개의 댓글