OAuth(Open Authorization)

4 분 소요


RECOMMEND POSTS BEFORE THIS

0. 들어가면서

OAuth(Open Authorization)는 많이 사용되는 인증(authentication), 인가(authorization) 방식입니다. 직접 구현은 해봤지만, 정확한 이론에 대해 정리해 본 적이 없었습니다. 이번 프로젝트에서 팀원들에게 관련된 내용을 공유하는 시간이 있었는데, 블로그 글로 함께 정리하면 좋을 것 같다는 생각에 포스트로 작성하였습니다.

1. OAuth(Open Authorization)

Wikipedia - OAuth
인터넷 사용자가 비밀번호를 제공하지 않고 특정 웹 사이트나 어플리케이션에서 다른 웹 사이트의 정보에 대한 접근을 허용하는 방법이다.

인증, 인가 표준 방식으로 Amazon, Google, Facebook, Microsoft, Twitter 같은 회사들(이하 서비스 제공자)에서 사용되고 있습니다. 인터넷 사용자가 서드-파티(third-party) 어플리케이션에서 서비스 제공자의 기능들을 사용하고 싶어할 때 발생할 수 있는 보안 문제를 해결한 인증 방식입니다. 서비스 제공자의 기능들을 사용하기 위해 사용자의 아이디, 비밀번호를 서드-파티 어플리케이션에게 직접 제공하는 것은 매우 위험한 일 입니다.

  • 서드-파티 어플리케이션이 안전한 서비스인지 알 수 없습니다.
  • 서드-파티 어플리케이션 입장에서도 사용자의 아이디, 비밀번호를 관리하는 것은 부담스럽습니다.

OAuth 방식은 서드-파티 어플리케이션이 사용자의 아이디, 비밀번호 없이 서비스 제공자의 기능들을 사용할 수 있는 권한을 위임 받는 방식입니다. 어떻게 아이디, 비밀번호 없이 서비스 제공자의 기능들을 사용할 수 있는 권한을 위임 받는지 자세히 살펴보겠습니다.

1.1. History

OAuth는 2006년 11월 Twitter 개발자와 Magnolia의 개발자들이 OpenID 구현에 관련된 내용을 논의하기 위해 만나게 되면서 시작합니다. 그들은 API 접근 위임에 관련된 공개 표준(open standard)이 없는 것을 확인하고, 2007년 4월에 OAuth 논의체를 만듭니다. OAuth 공개 프로토콜 제안서 초안을 작성하여 공개하고, 많은 지지를 받습니다. 2010년 IETF(Internet Engineering Task Force)에서 OAuth 1.0 공식 표준안이 RFC 5849로 발표됩니다.

OAuth 2.0 프레임워크는 IETF 커뮤니티에 수집된 추가 사례와 확장성을 고려하여 이 후에 발표되었습니다. OAuth 1.0 배포 환경을 기반으로 구축되었지만, 역호환되지 않습니다. 2012년 10월에 OAuth 2.0은 RFC 6749, 베어러(bearer) 토큰 사용은 RFC 6750으로 발표됩니다.

2. Roles

OAuth1.0은 2009년 4월에 보안 결함에 관련된 내용이 발표되었으며, 현재는 주로 OAuth2.0 프로토콜을 사용합니다. OAuth2.0을 기준으로 해당 프로토콜은 다음과 같은 참여자들에 의해 흐름이 진행됩니다.

  • Resource Owner(이하 리소스 소유자)
    • 일반 인터넷 사용자를 의미합니다.
  • Resource Server(이하 리소스 서버)
    • 일반 인터넷 사용자의 리소스를 관리하는 서비스 제공자를 의미합니다.
    • Amazon, Google, Facebook, Microsoft, Twitter
  • Client(이하 클라이언트)
    • 서드-파티 어플리케이션을 의미합니다.
    • 리소스 소유자의 권한을 위임받아 리소스 서버의 서비스를 제공하고 싶은 어플리케이션입니다.
    • 다음과 같은 어플리케이션을 예로 들수 있습니다.
      • 구글 로그인을 연동한 웹 서비스
      • 트위터 로그인, 트위터에 글쓰기가 가능한 웹 서비스
  • Authorization Server(이하 인가 서버)
    • 액세스 토큰(access token)을 클라이언트에게 제공하는 서버입니다.
    • 액세스 토큰을 발급받은 클라이언트는 이후 인증과 인가를 통해 리소스 소유자에게 리소스 서버의 서비스를 제공할 수 있습니다.
    • 리소스 서버와 동일한 서버일 수도 있고, 분리된 별도의 서비스일 수도 있습니다.

3. Register Process

클라이언트 어플리케이션이 리소스 소유자에게 리소스 서버의 서비스를 제공하려면 등록 과정이 필요합니다. 이 과정은 클라이언트 어플리케이션이 리소스 소유자의 권한을 위임 받을 수 있도록 미리 승인을 받는 것 입니다. Github 로그인 연동 과정을 기준으로 설명을 이어가겠습니다.

3.1. Register Client Application on Github

Github 사이트에서 오른쪽 프로필 사진을 눌러 Settings 화면으로 이동합니다. Developers settings > OAuth Apps > Register a new application으로 접근하여 클라이언트 등록 화면으로 이동합니다. 다음과 같은 정보를 입력합니다.

  • Application name
    • 클라이언트 어플리케이션의 이름
  • Homepage URL
    • 클라이언트 어플리케이션의 메인 홈페이지 URL
    • e.g. http://application-public-address
  • Authorization callback URL
    • 클라이언트 어플리케이션이 인가 서버로부터 인증 코드를 받을 수 있는 URL
    • e.g. http://application-public-address/auth/callback

3.2. Client ID and Secret

클라이언트 어플리케이션을 등록하면 다음과 같은 정보를 확인할 수 있습니다.

  • CLIENT ID
    • 클라이언트 어플리케이션의 아이디입니다.
    • 인가 서버는 클라이언트 ID를 통해 인증 요청이 어느 어플리케이션으로부터 왔는지 알 수 있습니다.
  • CLIENT SECRET
    • 클라이언트 어플리케이션의 비밀 키이며 외부로 노출되면 안됩니다.
    • 인가 서버는 클라이언트 SECRET을 통해 인증 요청이 유효한지 판정합니다.

3.3. OAuth Scope

인가 서버로부터 발급 받은 액세스 토큰으로 접근할 수 있는 리소스, 기능들의 범위를 의미합니다. 액세스 토큰으로 모든 리소스 서버의 기능을 사용할 수는 없습니다. 등록 과정에서 필요한 리소스나 기능들을 결정하면, 클라이언트 어플리케이션은 발급 받은 액세스 토큰으로 허용된 스코프에 대한 기능들만 서비스할 수 있습니다. 아래 링크는 클라이언트 어플리케이션의 스코프와 관련된 가이드 라인을 제공합니다.

4. Authentication Process

인증은 다음과 같은 과정을 거쳐 이뤄집니다.

  1. (A) Authorization Request
    • 클라이언트 어플리케이션은 리소스 소유자(사용자)에게 권한 위임을 요청합니다.
    • 보통 이 과정에서 리소스 소유자는 리소스 서버의 로그인 화면으로 브라우저 리다이렉트(redirect)를 통해 연결됩니다.
    • 리소스 소유자는 로그인을 수행합니다.
  2. (B) Authorization Grant
    • 리소스 소유자가 로그인을 수행하면 권한 위임에 대한 자격 증명(credential)이 클라이언트 어플리케이션에게 전달됩니다.
    • 보통 등록 과정에서 입력한 callback URL으로 자격 증명을 전달받습니다.
    • 권한 부여 유형은 여러 가지 존재하며 권한 부여 서버에서 지원하는 방식에 따라 달라집니다.
      • Authorization Code
      • Implicit
      • Resource Owner Password Credentials
      • Client Credentials
  3. (C) Authorization Grant
    • 클라이언트 어플리케이션은 액세스 토큰 발급을 위해 권한 위임에 대한 자격 증명을 인가 서버로 전달합니다.
  4. (D) Access Token
    • 인가 서버는 권한 위임에 대한 자격 증명의 유효성을 확인합니다.
    • 정상적인 경우 액세스 토큰을 클라이언트 어플리케이션에게 전달합니다.
  5. (E) Access Token
    • 클라이언트는 보호된 리소스를 리소스 서버로 요청합니다.
    • 인가 서버로부터 발급받은 액세스 토큰을 함께 전달하여 인증과 인가를 수행합니다.
  6. (F) Protected Resource
    • 리소스 서버는 전달받은 액세스 토큰이 유효한 경우 요청에 정상적으로 응답합니다.

https://www.rfc-editor.org/rfc/rfc6749

5. Refresh Token

리프레시 토큰(refresh token)은 인가 서버로부터 발급 받습니다. 아래와 같은 경우 새로운 액세스 토큰을 발급 받기 위해 사용합니다.

  • 현재 액세스 토큰이 만료되는 경우
  • 더 넓거나 좁은 스코프 범위를 가지는 액세스 토큰을 새로 발급 받는 경우

다음과 같은 프로세스를 거쳐 새로운 액세스 토큰을 발급 받습니다.

  1. (A) Authorization Grant
    • 클라이언트 어플리케이션은 인가 서버에게 자격 증명을 전달하여 액세스 토큰을 요청합니다.
  2. (B) Access Token & Refresh Token
    • 자격 증명으로 인증 처리가 되면 인가 서버는 클라이언트 어플리케이션에게 액세스 토큰과 리프레시 토큰을 전달합니다.
  3. (C) Access Token
    • 클라이언트 어플리케이션은 액세스 토큰으로 필요한 리소스를 리소스 서버에게 요청합니다.
  4. (D) Protected Resource
    • 리소스 서버는 보호된 리소스를 클라이언트 어플리케이션에게 전달합니다.
  5. (E) Access Token
    • 클라이언트 어플리케이션은 액세스 토큰으로 필요한 리소스를 리소스 서버에게 요청합니다.
  6. (F) Invalid Token Error
    • 리소스 서버는 액세스 토큰이 유효하지 않다면 에러를 클라이언트 어플리케이션에게 전달합니다.
  7. (G) Refresh Token
    • 클라이언트 어플리케이션은 리프레시 토큰을 인가 서버에게 전달하며 새로운 액세스 토큰을 요청합니다.
  8. (H) Access Token & Optional Refresh Token
    • 인가 서버는 리프레시 토큰이 유효한 경우 새로운 액세스 토큰을 클라이언트 어플리케이션에게 전달합니다.
    • 리프레시 토큰은 선택적으로 전달합니다.

https://www.rfc-editor.org/rfc/rfc6749

CLOSING

브라우저의 리다이렉트 처리에 대한 이해도가 낮은 경우 인증 프로세스를 이해하는 데 어려움을 겪습니다. 특히 요즘처럼 프론트엔드와 백엔드 서비스가 나눠진 경우엔 더 헷갈리기 때문에 기본기에 대한 공부가 필요합니다.

RECOMMEND NEXT POSTS

REFERENCE

댓글남기기