danbibibi
article thumbnail

OAuth 2.0

"비밀번호를 직접 공유하던 시절"과 비교했을 때의 보안 향상

비밀번호 노출 제3자 앱이 비밀번호를 평문으로 알게 됨
권한 제어 불가 비밀번호를 주면 모든 권한이 넘어감 (이메일만 필요한데 결제 정보까지 접근 가능)
회수 불가 접근을 끊으려면 비밀번호 자체를 변경해야 함
연쇄 피해 한 앱에서 유출되면 같은 비밀번호를 쓰는 모든 서비스가 위험

이외에도,

  • UX 향상: "Google로 로그인" 같은 간편 로그인
  • 표준화: 모든 서비스가 같은 프로토콜로 연동 가능
  • 관리 편의: 사용자가 "연결된 앱" 목록에서 개별적으로 권한 회수 가능

주요 구성요소(Component)와 그 역할 (Role)

  • 리소스 소유자(Resource Owner)
    접근에 인증이 필요한 리소스(Resource)에 대해서 접근하고자 하는 Entity 입니다. 만약 유저가 이를 이용하고 싶다고 한다면 end-user가 될 수도 있고 만약 다른 서버가 사용을 원한다면 리소스 소유자는 해당 서버가 될 수도 있습니다. 즉, 이는 리소스를 사용하고자 요청을 보내는 주체입니다.
  • 인증 서버(Authorization Server)
    리소스에 대한 접근 권한 등을 관리하고 있는 서버입니다. 리소스 서버에 리소스 소유자가 클라이언트를 이용하여 접근할 수 있도록 Access Token을 만들어주는 서버이기도 하며 Grant Type을 관리하고 인증 정보를 관리하기도 합니다.
  • 리소스 서버(Resource Server)
    리소스가 존재하고 있는 서버입니다. 이 서버는 리소스를 가지고 있고 해당 리소스를 접근 권한이 있는 사용자에게만 접근할 수 있도록 허용합니다. 대표적으로 JWT를 Access Token으로 이용한다면 리소스 서버는 이를 verify하여 인증과 인과를 확인하여 접근 여부를 판단합니다. 간단히 말해서 정보를 가지고 있는 API 서버라고 볼 수 있습니다.
  • 클라이언트(Client)
    리소스 소유자를 대신하여 리소스 서버에 리소스를 요청하는 어플리케이션입니다. 웹, 모바일 앱, 데스크 탑 어플리케이션이라고 봐주시면 됩니다.

 

 

  1. 클라이언트는 리소스 소유자에게 권한얻기 위해서 인증을 요청합니다. 권한 부여는 리소스 소유자가 직접 할수도 있습니다. 하지만 대체적으로 로그인 등과 같이 인증 서버에 위임하여 간접적으로 요청하는것이 일반적입니다.
  2. 인증이 완료되면 Client는 authorization grant중 한가지와 이에 해당하는 정보들을 받습니다. 권한 부여 유형은 기 정의되 내용으로 각 서비스마다 다를 수 있습니다.
    Grant Type 사용 상황 흐름
    Authorization Code 일반 웹/앱 (가장 보편적) 사용자 로그인 → code 발급 → code로 토큰 교환
    Client Credentials 서버 간 통신 (사용자 개입 없음) Client가 직접 자격증명으로 토큰 발급
    Refresh Token 토큰 갱신 기존 Refresh Token으로 새 Access Token 발급
  3. 2번에서 얻은 정보와 Client가 기존에 가지고 있던 정보를 가지고 인증 서버(Authorization Server)에 Access Token을 요청합니다.
  4. 인증 서버는 클라이언트가 전달한 정보 및 Authorization Granth의 유효성을 검증합니다. 검증이 정상적으로 완료되면 Access Token을 발급해줍니다.
  5. 클라이언트는 Access Token을 이용하여 리소스 서버에 리소스에 접근한다는 요청을 합니다.
  6. 적절한 Access Token인지 Resource Server에서 검증한 후 검증이 완료되었다면 서버에서 리소스를 반환합니다.

 

위의 Flow를 보았을 때 실제로 리소스 소유자가 본인을 인증하는 것은 1번밖에 없습니다.
나머지는 시스템끼리 주고 받는 flow입니다. 1번의 인증 이후에 실제로 리소스에 접근하기 위해서 필요한것은 Access Token입니다.
결과적으로 리소스 접근에 대해서 유저의 Access Token이 만약 탈취되더라도 인증 정보는 무사하기 때문에 Access Token만 만료 시키면 안전성을 유지할 수 있습니다.

 

OAuth 2.0이 제3자 액세스를 사용자 리소스에 승인하는 데는 뛰어나지만, 제한이 있습니다. 일반적인 시나리오는 사용자 정보도 리소스이기 때문에 제3자 애플리케이션이 기본적인 사용자 정보에 접근해야 할 때, 다양한 플랫폼(Google, Facebook, Twitter 등)이 서로 다른 형식으로 사용자 정보를 반환하므로 개발자에게 도전을 줍니다.

 

OIDC(OpenID Connect)

  • OAuth2의 확장중 하나로써 인증(Authentication)에 대한 프로토콜
  • OAuth 2.0 위에 구축된 인증(Authentication) 레이어입니다. OAuth 2.0이 "무엇에 접근할 수 있는가"를 다룬다면, OIDC는 "이 사용자가 누구인가" 를 다룹니다.
    • OAuth 2.0 (인가) + OIDC (인증) = 완전한 인증/인가 솔루션

OIDC가 추가하는 핵심 요소

  • OAuth 2.0의 Access Token과 별도로 사용자 신원 정보를 담은 토큰을 발급 (ID Token)
    JWT 형식으로 sub, name, email 등 필드명이 통일
  • UserInfo Endpoint
    ID Token 외에 추가 사용자 정보를 조회할 수 있는 표준 API 엔드포인트
    /userinfo라는 표준 엔드포인트 제공
  • Discovery Document
    /.well-known/openid-configuration 경로에서 서버의 모든 엔드포인트와 지원 기능을 자동 탐색
  • 어떤 플랫폼이든 OIDC를 지원하면 같은 코드로 사용자 정보를 처리 가능

인증과 인가의 차이

  • 인증(Authentication): 사용자의 신원을 확인하는 과정입니다. 로그인과 같은 방식으로 사용자가 누구인지 증명합니다.
  • 인가(Authorization): 인증된 사용자에게 특정 자원에 대한 접근 권한을 부여하는 과정입니다. 접근 제어를 위해 사용됩니다.

OAuth2와 OIDC의 차이점

  • OAuth2: 인가 프로토콜로서, 인증된 사용자에게 자원 접근 권한을 부여하는 것에 중점을 둡니다.
  • OIDC: OAuth 2.0을 확장하여, 사용자의 인증 정보를 안전하게 전달하는 인증 프로토콜입니다.

OIDC 인증 흐름

사용자 → Client: 로그인 요청
Client → Authorization Server: scope에 "openid" 포함하여 요청
Authorization Server → 사용자: 로그인 + 동의 화면
사용자 → Authorization Server: 인증 완료
Authorization Server → Client: Authorization Code
Client → Authorization Server: Code 교환
Authorization Server → Client: Access Token + ID Token (★)
Client: ID Token 검증 → 사용자 신원 확인
Client → Resource Server: Access Token으로 API 호출

 

비교 요약

구분 OAuth 2.0 OIDC
목적 인가 (Authorization) 인증 (Authentication)
핵심 질문 "이 앱이 무엇에 접근할 수 있는가?" "이 사용자가 누구인가?"
발급 토큰 Access Token, Refresh Token + ID Token
토큰 형식 규정 없음 (opaque 가능) JWT (표준화)
사용자 정보 표준 없음 UserInfo Endpoint 표준 제공

 

OAuth 2.0은 "이 앱이 리소스에 접근해도 되는가"만 다루고, "로그인한 사용자가 누구인가"는 범위 밖이었습니다.
OIDC는 그 위에 사용자 정보(누구인지)를 표준화된 형식으로 전달하는 레이어를 얹은 것이지, 보안 메커니즘 자체를 강화한 건 아닙니다.
profile

danbibibi

@danbibibi

꿈을 꾸는 시간은 멈춰 있는 것이 아냐 두려워하지 마 멈추지 마 푸른 꿈속으로