치춘짱베리굿나이스

OAuth 본문

이론적인 부분들/웹

OAuth

치춘 2023. 7. 25. 14:31

OAuth

우리의 42 마지막 과제인 ft_transcendence 로그인 페이지의 일부분이다

42 네트워크의 OAuth를 통해 로그인이 가능하도록 만들어진 것을 볼 수 있다

그렇긴 한데,, OAuth는 어떻게 동작하는 것일까? 나는 그걸 알고 만든거긴 할까? 라는 의문이 들어서 이제와서 (…) 정리해보려고 한다

ft_transcendence (42 과제) 기준으로 작성된 포스팅이라 42 향이 진하게 묻어있을 수 있다

정의

OAuth 2.0 웹사이트에서의 설명

https://oauth.net

웹, 모바일, 데스크톱 애플리케이션에서 사용되는, 간단하고 표준적인 방법으로 안전하게 인가를 받을 수 있는 개방형 프로토콜
OAuth 2.0 is the industry-standard protocol for authorization. OAuth 2.0 focuses on client developer simplicity while providing specific authorization flows for web applications, desktop applications, mobile phones, and living room devices. This specification and its extensions are being developed within the IETF OAuth Working Group.

OAuth 2.0은 인가 (권한 부여) 를 위한 업계 표준 프로토콜입니다. OAuth 2.0은 클라이언트 개발에서의 단순성에 중점을 두고 웹 어플리케이션, 데스크톱 어플리케이션, 휴대폰 및 가구 등의 장치에 특정한 권한 플로우를 제공합니다. 이 규격과 확장은 IETF Oauth Working Group에 의해 개발되고 있습니다.

설명

OAuth (Open Authorization)

비밀번호 등의 민감한 정보를 제공하지 않고도 다른 웹사이트의 특정 유저 정보에 대한 접근 권한을 부여받을 수 있는 개방형 표준이다

  • 예를 들어, 구글 OAuth를 사용하는 웹사이트가 있다고 해 보자
  • 우리가 웹 사이트에 구글 계정 정보를 넘기지 않아도 OAuth를 통해 웹 사이트가 구글 계정 정보 일부에 접근하고 사용할 수 있게 해 준다

OAuth 등장인물 (?)

  • Resource Owner
    • 비공개 자원들을 가지고 있고, 자원들에 접근 권한을 부여할 수 있는 주체
    • 후술할 Client를 사용하는 사용자들으로, OAuth 프로토콜에서는 인증 절차를 거쳐 자신의 비공개 자원 접근 권한을 Client에 제공하게 된다
  • Resource Server
    • 사용자들의 비공개 자원을 실제로 들고 있는 장소
    • OAuth를 제공해주는 웹사이트, 즉 구글이나 깃허브, 카카오 등이 이에 속한다
  • Client
    • 사용자 (Resource Owner) 의 비공개 자원에 접근하고 싶어 하는 어플리케이션 또는 웹 사이트
    • OAuth를 사용하는 서드파티 어플리케이션이 클라이언트가 된다
  • Authorization Server
    • 유저 인증을 거치고 Access Token, Refresh Token 등을 발급해 주는 권한 서버
    • 인증과 인가는 이 서버에서 담당한다

OAuth 용어

https://blog.chichoon.com/760

https://blog.chichoon.com/767

전에 정리한 게 하나 있다

  • Authentication (인증)
    • 당신이 내가 아는 그 사람이 맞소?
  • Authorization (인가 = 권한 부여)
    • 당신은 내가 생각하는 그 사람이오. ~~에 대한 접근 권한을 드리겠소.
  • Access Token
    • Resource Server의 사용자 자원을 접근할 수 있게 도와주는 토큰
  • Refresh Token
    • Access Token이 만료되었을 때 이를 재발급 받기 위한 토큰

OAuth 흐름

0. Application 등록

먼저 OAuth를 제공하는 주체에 우리의 어플리케이션을 등록해야 한다

예시는 42 API 등록 창인데, 다른 서비스도 별반 다를 것은 없다

Redirection URI (또는 Authorization Callback URL) 에는 인증 성공 후 리디렉션될 웹 사이트 주소를 입력하면 되고, 해당 주소로 Authorization Code가 전달된다

 

어플리케이션 등록 시에 해당 어플리케이션이 접근 가능한 비공개 데이터의 범위도 설정해줄 수 있는 경우가 대부분이다

 

등록 완료하면 요로코롬 IDSECRET을 부여받는다 (예시는 42이지만 대부분의 OAuth 앱이 이러한 형태이다)

ID는 클라이언트를 식별하기 위한 식별자로 사용되고, SECRET은 Access Token을 발급받기 위한 비밀 키라고 생각하면 된다

특히 SECRET은 공개하면 안 되므로 환경변수에 추가하여 사용하는 경우가 많다

1. 클라이언트로부터 로그인 요청

사용자 (Resource Owner) 는 제 3자 앱 (Client) 에서 해당 버튼을 클릭하여 로그인을 요청함으로써 OAuth 플로우가 시작된다

여기서 클라이언트는 대개 사용자를 Authorization Server로 리디렉션 시킨다

 

https://auth.42.fr/auth/realms/students-42/protocol/openid-connect/auth
?client_id=클라이언트아이디
&redirect_uri=리디렉션URI
&response_type=응답형식
&state=상태
https://accounts.google.com/v3/signin/identifier
?opparams=opparams
&dsh=dsh
&client_id=클라이언트ID
&nonce=nonce
&o2v=o2v
&redirect_uri=리디렉션URI
&response_type=응답형식
&scope=권한종류
&service=service
&flowName=flow종류
&continue=continue
&app_domain=어플리케이션도메인
&rart=rart

Authorization Server로 사용자를 보낼 때엔 특별한 정보를 포함하여 보내야 하는데, 이때 Authorization Server에서 명시하는 주소 (Authorization URL) 에 쿼리 패러미터로 데이터를 엮어 전송한다

구글이 특이하게 보내야 하는 데이터가 많은데… 42나 깃허브는 4개 정도가 전부라고 한다

대표적인 쿼리 패러미터는 다음과 같다

  • client_id: 어플리케이션 등록 시에 발급받았던 ID
  • redirect_uri: 어플리케이션 등록 시에 등록해줬던 리디렉션 주소
  • scope: 클라이언트에게 부여된 자원 접근 권한

결과적으로 사용자는 정보가 쿼리스트링으로 합쳐진 URL에 접속하여 로그인을 시도하게 된다

  • 프론트엔드 사이드에서 노출되면 위험한 정보가 있을 수 있어, 위의 쿼리 URL은 보통 백엔드에서 구성하고, 프론트엔드는 백엔드에 GET 요청하여 리다이렉트 하는 방식으로 구현하였다

2. 패러미터 검증

Authorization Server는 쿼리 패러미터를 받아 이를 검증한다

Client ID는 유효한지, Client ID에 대응하는 Redirection URI는 유효한지, 접근 권한은 정상적인지, 기타 패러미터들은 유효한지… 등등을 검사한다

 

패러미터가 정상적이지 않을 경우, 로그인 시도 자체가 불가능하게 막힌다

3. 로그인

사용자 (Resource Owner) 가 https://auth.42.fr/auth… 링크에 접속하게 되면, 쿼리 패러미터가 정상일 경우에 위와 같은 화면을 볼 수 있다

여기서 사용자는 자신의 아이디와 비밀번호를 입력함으로서 인증 절차를 거친다

 

로그인을 완료하면 위와 같은 창이 뜨는데, 사용자는 여기서 클라이언트에 자신의 정보에 대한 권한을 인가할 지 결정할 수 있다

어떤 정보에 대한 권한이 어떤 앱에게 인가되는지 명시되어 있으므로 잘 보고 판단할 수 있다

4. Authorization Code 발급과 함께 리디렉션

앞 화면에서 사용자 (Resource Owner) 가 권한 인가를 허가하면 그 다음에는 앞서 명시한 Redirection URI로 사용자를 리다이렉트 시킨다

이때 쿼리스트링으로 Authorization Code를 함께 발급해 주는데, 이는 Access Token을 받기 전에 임시로 사용되는 코드이다

이 코드는 수명이 매우 짧기 때문에, 빠르게 Access Token을 발급받는 것이 좋다

 

https://localhost:8080/login

만약 Redirection URI가 위와 같다면,

 

https://localhost:8080/login?code=어쩌구저쩌구....

코드는 대개 이러한 쿼리스트링 방식으로 전달받는다

5. Access Token, Refresh Token 발급

클라이언트는 Authorization Server에 위 코드와 매개변수 몇 가지를 전달하여 토큰을 응답받는다

  • 필요한 매개변수로는 최초로 발급받은 ID (Client ID), SECRET (Client Secret), code (방금 발급받은 코드) 등이 있다
    • 권한 부여 방식은 후술할 authorization_code (권한 부여 승인 코드 방식) 으로 지정하면 된다
  • 프론트엔드 사이드에서는 위 쿼리스트링을 파싱하여 코드를 취득한 후, 이를 백엔드로 전달한다
  • 백엔드 사이드에서는 이 코드를 이용하여 Authorization Server로부터 Access Token 과 Refresh Token을 발급받는다

6. 로그인 후, 데이터 요청

Access Token과 Refresh Token을 받았으면, 이를 헤더에 담아 Resource Server에 데이터를 요청한다

Resource Server는 토큰을 검사하여 권한이 인가되었음을 파악하고, 필요한 자원을 내려준다

OAuth 권한 부여 방식

권한 부여 승인 코드 방식 (Authorization Code Grant)

위의 플로우에서 사용된 방식으로, Authorization Code를 임시로 전달하여 이를 통해 Access Token (과 Refresh Token) 을 지급하는 방식이다

가장 많이 사용되는 기본적인 기법으로, Refresh Token 사용이 가능하다

클라이언트 자격증명 승인 방식 (Client Credentials Grant)

가장 간단한 방식으로, 사용자의 자원을 얻으려고 하기보단 클라이언트 자신에 관한 자원을 획득하려 할 때 사용되는 방식이다

Refresh Token 사용이 불가능하다

기기 증명 방식 (Device Authorization Grant)

브라우저를 거치지 않고 device flow를 통해 기기 코드 (Device Code) 를 취득하고, 이를 이용하여 Access Token을 얻어오는 방식이다

애플 TV 등 브라우저 없이 기기 독자적으로 데이터를 받아올 때 사용한다

암묵적 승인 방식 (Implicit Grant)

자격증명을 안전하게 저장하기 힘든 클라이언트에 최적화된 방식으로, 위의 코드 방식과 다르게 Authorization Code 없이 바로 Access Token을 지급한다

단 유출 위험을 방지하기 위해 Access Token의 기간이 매우 짧다

Refresh Token의 사용이 불가능하고, 인증에 SECRET 이 필요 없다

지금은 보안 위험 때문에 OAuth 공식 홈페이지에서는 Legacy 로 안내하고 있다

자원 소유자 자격증명 승인 방식 (Resource Owner Password Credentials Grant)

ID와 PW 만으로 Access Token을 지급받는 방식이다

ClientAuthorization Server, Resource Server 가 같은 서비스 제공자를 가질 경우에 (같은 시스템 내에 속해 있을 때) 사용가능하다

Refresh Token 사용이 가능하다

가장 최신 OAuth 버전에서는 허용되지 않는다고 한다

그 외

  • Proof Key for Code Exchange
    • Authorization Code Grant의 발전형으로, CSRF와 Authorization Code Injection을 방지하기 위해 등장했다

참고 자료

https://tecoble.techcourse.co.kr/post/2021-07-10-understanding-oauth/

https://hudi.blog/oauth-2.0/

https://charming-kyu.tistory.com/36

https://oauth.net/2/grant-types/

'이론적인 부분들 > ' 카테고리의 다른 글

WebSocket  (0) 2023.07.21
CORS  (0) 2023.06.17
DOM과 웹 렌더링  (0) 2023.05.19
JWT  (0) 2022.10.10
로그인, 인증, 인가  (0) 2022.10.08
Comments