티스토리 뷰

Tips/보안

[보안] OAuth 2.0 개념 및 동작 원리

무화과(Fig) 2023. 8. 16. 01:24

목차

1. OAuth란?
2. OAuth 참여자
3. Client 등록
4. OAuth 2.0의 동작 메커니즘
5. OAuth 2.0의 스코프


 
 
 

 

1. OAuth란?


OAuth: 구글, 페이스북, 트위터와 같은 다양한 플랫폼의 특정한 사용자 데이터에 접근하기 위해 제3자 클라이언트(우리의 서비스)가 사용자의 접근 권한을 위임(Delegated Authorization)받을 수 있는 표준 프로토콜

쉽게 말해, 우리의 서비스가 우리 서비스를 이용하는 유저의 타사 플랫폼 정보에 접근하기 위해서 권한을 타사 플랫폼으로부터 위임 받는 것이다.

 
 
 
 

2. OAuth 참여자


OAuth 동작에 관여하는 참여자는 크게 세 가지로 구분할 수 있다.
 

1. Resource Owner

Client가 제공하는 서비스를 통해 로그인하는 실제 유저

 

2. Authorization & Resource Server

Client가 제어하고자 하는 자원을 보유하고 있는 서버  ex. Facebook, Google, Twitter 등

 

3. Client

Resoure Server에 접속해서 정보를 가져오고자 하는 클라이언트(웹 어플리케이션). 우리가 개발하려는 서비스이다.

 
 
 
 

3. Client 등록


Client(웹 어플리케이션)가 Resource Server를 이용하기 위해서는 자신의 서비스를 등록함으로써 사전 승인을 받아야 한다. 이때, Redirect URI를 등록해야한다.
 
Redirect URI는 사용자가 OAuth 2.0 서비스에서 인증을 마치고 (예를 들어 구글 로그인 페이지에서 로그인을 마쳤을 때) 사용자를 리디렉션시킬 위치이다.
 
 
등록 절차를 통해 다음과 같은 세 가지 정보를 부여받는다.

 

  1. Client ID : 클라이언트 웹 어플리케이션을 구별할 수 있는 식별자이며, 노출해도 무방하다.
  2. Client Secret : Client ID에 대한 비밀키로서, 절대 노출해서는 안된다.
  3. Authorized redirect URL : Authorization Code를 전달받을 리다이렉트 주소다.

 

Redirect URI

OAuth 2.0 서비스는 인증이 성공한 사용자를 사전에 등록된 Redirect URI로만 리디렉션 시킨다. 승인되지 않은 URI로 리디렉션 될 경우, Authorization Code를 중간에 탈취당할 위험성이 있기 때문이다. 일부 OAuth 2.0 서비스는 여러 Redirect URI를 등록할 수 있다.

Redirect URI는 기본적으로 보안을 위해 https만 허용된다. 단, 루프백(localhost)은 예외적으로 http가 허용된다.

 
 
 
 

4. OAuth 2.0의 동작 메커니즘


OAuth 2.0 동작과정 시퀀스 다이어그램

 
 
 

1 ~ 2. 로그인 요청

Resource Owner가 우리 서비스의 '구글로 로그인하기' 등의 버튼을 클릭해 로그인을 요청한다. Client는 OAuth 프로세스를 시작하기 위해 사용자의 브라우저를 Authorization Server로 보내야한다.
 
클라이언트는 이때 Authorization Server가 제공하는 Authorization URL에 response_type , client_id , redirect_uri , scope 등의 매개변수를 쿼리 스트링으로 포함하여 보낸다.
 

쿼리 스트링: 사용자가 입력 데이터를 전달하는 방법중의 하나로, url 주소에 미리 협의된 데이터를 파라미터를 통해 넘기는 것을 말한다.

http://host:port/path?querystring

query parameters( 물음표 뒤에 = 로 연결된 key value pair 부분)을 url 뒤에 덧붙여서 추가적인 정보를 서버 측에 전달하는 것이다. 클라이언트가 어떤 특정 리소스에 접근하고 싶어하는지 정보를 담는다.


형식

- 정해진 엔드포인트 주소 이후에 ?를 쓰는것으로 쿼리스트링이 시작함을 알린다.
- parameter=value로 필요한 파라미터의 값을 적는다.
- 파라미터가 여러개일 경우 &를 붙여 여러개의 파라미터를 넘길 수 있다.
  엔드포인트주소/엔드포인트주소?파라미터=값&파라미터=값
- = 로 key 와 value 가 구분된다.

 
예를 들어 어떤 OAuth 2.0 서비스의 Authorization URL이 https://authorization-server.com/auth 라면, 결과적으로 Client는 아래와 같은 URL을 빌드할 것이다.

https://authorization-server.com/auth?response_type=code
&client_id=29352735982374239857
&redirect_uri=https://example-app.com/callback
&scope=create+delete

 
이때 Authorization Server에게 보낼 매개변수는 아래와 같다.

  • response_type : 반드시 code 로 값을 설정해야한다. 인증이 성공할 경우 클라이언트는 Authorization Code를 받을 수 있다.
  • client_id : 애플리케이션을 생성했을 때 발급받은 Client ID
  • redirect_uri : 애플리케이션을 생성할 때 등록한 Redirect URI
  • scope : 클라이언트가 부여받은 리소스 접근 권한

 

 
 

3 ~ 4. 로그인 페이지 제공, ID/PW 제공

클라이언트가 빌드한 Authorization URL로 이동된 Resource Owner는 제공된 로그인 페이지에서 ID와 PW 등을 입력하여 인증할 것이다.
 
 
 

5 ~ 6. Authorization Code 발급, Redirect URI로 리디렉트

인증이 성공되었다면, Authorization Server 는 제공된 Redirect URI로 사용자를 리디렉션시킬 것 이다. 이때, Redirect URI에 Authorization Code를 포함하여 사용자를 리디렉션 시킨다. (구글의 경우 코드를 쿼리 스트링에 포함한다.)

 

Authorization Code
Client가 Access Token을 획득하기 위해 사용하는 임시 코드. 이 코드는 수명이 매우 짧다. (일반적으로 1~10분)

 
 

7 ~ 8. Authorization Code와 Access Token 교환

Client는 Authorization Server에 Authorization Code를 전달하고, Access Token을 응답받는다.
Client는 발급받은 Resource Owner의 Access Token을 저장하고, 이후 Resource Server에서 Resource Owner의 리소스에 접근하기 위해 Access Token을 사용한다.
 

Access Token은 유출되어서는 안된다. 따라서 제 3자가 가로채지 못하도록 HTTPS 연결을 통해서만 사용될 수 있다.

 
Authorization Code와 Access Token 교환은 token 엔드포인트에서 이루어진다. 아래는 token 엔드포인트에서 Access Token을 발급받기 위한 HTTP 요청의 예시이다. 이 요청은 application/x-www-form-urlencoded 의 형식에 맞춰 전달해야한다.

POST /oauth/token HTTP/1.1
Host: authorization-server.com

grant_type=authorization_code
&code=xxxxxxxxxxx
&redirect_uri=https://example-app.com/redirect
&client_id=xxxxxxxxxx
&client_secret=xxxxxxxxxx

 
필수로 전달해야하는 매개변수를 살펴보자.

  • grant_type : 항상 authorization_code 로 설정되어야 한다.
  • code : 발급받은 Authorization Code
  • redirect_uri : Redirect URI
  • client_id : Client ID
  • client_secret : RFC 표준상 필수는 아니지만, Client Secret이 발급된 경우 포함하여 요청해야한다

 
 

Authorization Code가 필요한 이유


Authorization Code를 발급하지 않고, 곧바로 Client에게 Access Token을 발급해줘도 되지 않을까? 왜 굳이 Access Token을 획득하는 과정에 Authorization Code 발급 과정이 필요할까?

Redirect URI를 통해 Authorization Code를 발급하는 과정이 생략된다면, Authorization Server가 Access Token을 Client에 전달하기 위해 Redirect URI를 통해야 한다. 이때, Redirect URI를 통해 데이터를 전달할 방법은 URL 자체에 데이터를 실어 전달하는 방법밖에 존재하지 않는다. 브라우저를 통해 데이터가 곧바로 노출되는 것 이다.

하지만, Access Token은 민감한 데이터이다. 쉽게 노출되어서는 안된다. 따라서 이런 보안 사고를 방지 Authorization Code를 사용하는 것이다.

Redirect URI를 프론트엔드 주소로 설정하여, Authorization Code를 프론트엔드로 전달한다. 그리고 이 Authorization Code는 프론트엔드에서 백엔드로 전달된다. 코드를 전달받은 백엔드는 비로소 Authorization Server의 token 엔드포인트로 요청하여 Access Token을 발급한다.

이런 과정을 거치면 Access Token이 항상 우리의 어플리케이션과 OAuth 서비스의 백채널을 통해서만 전송되기 때문에 공격자가 Access Token을 가로챌 수 없게된다.

 
 

 

9. 로그인 성공

위 과정을 성공적으로 마치면 Client는 Resource Owner에게 로그인이 성공하였음을 알린다.

 
 
 
 

10 ~ 13. Access Token으로 리소스 접근

이후 Resource Owner가 Resource Server의 리소스가 필요한 기능을 Client에 요청한다. Client는 위 과정에서 발급받고 저장해둔 Resource Owner의 Access Token을 사용하여 제한된 리소스에 접근하고, Resource Owner에게 자사의 서비스를 제공한다.

 
 
 
 

 

5. OAuth 2.0의 스코프


인증된 사용자만 API에 접근하게 하려면 API 보안이 매우 중요하다. OAuth 2.0은 스코프라는 개념을 통해서 유저 리소스에 대한 클라이언트의 접근 범위를 제한할 수 있다.
스코프는 여러개가 될 수 있으며, 대소문자를 구문하는 문자열을 공백으로 구분하여 표현된다. 이때 문자열은 OAuth 2.0 인증 서버에 의해 정의된다.
 

스코프(Scope)
클라이언트에게 허용된 리소스의 범위를 저장한다.

 
예를 들어 우리의 서비스가 사용자의 구글 연락처를 받아오고 싶다면, OAuth 2.0 스코프에 연락처 스코프 문자열을 포함하여 OAuth 2.0 제공자에게 전달하면 된다. 그렇다면 사용자는 아래의 사진과 같이 스코프에 명시된 권한을 요청하는 화면을 볼 수 있다
 

 
이 과정을 거쳐 발급된 액세스 토큰은 부여된 스코프에 해당하는 권한을 제한적으로 획득할 수 있다.
 
 

 
 
 
 

참고

https://tecoble.techcourse.co.kr/post/2021-07-10-understanding-oauth/
https://hudi.blog/oauth-2.0/
https://velog.io/@pear/Query-String-%EC%BF%BC%EB%A6%AC%EC%8A%A4%ED%8A%B8%EB%A7%81%EC%9D%B4%EB%9E%80

'Tips > 보안' 카테고리의 다른 글

AccessToken, RefreshToken 어디에 저장할까?  (0) 2023.10.31