2 minute read

Open Authorization 2.0(이하 OAuth2)은 인증을 위한 개발형 표준 프로토콜이다. OAtuth2는 클라이언트로 하여금 쉽게 인증 처리를 하면서도, 다양한 웹 어플리케이션 서비스에서 접근 권한을 부여할 수 있게 만들었다. 이를 통해 유저는 여러 서비스에 반복적으로 로그인하지 않고, 한 번의 인증으로 인증 절차를 스킵할 수 있게 되었다. 개발자는 인증 프로세스에 낭비하는 시간을 줄이고 보안적으로 안정한 기능을 구현하는 데 집중하게 되었고, 인터넷 생태계의 인증 표준이 되었다. 현재는 OAuth2의 기본 기능들을 단순화시키고 개선하는 OAuth2.1이 작업중이다.

OpenID Connect(이하 OIDC)는 OAuth2기반으로 만들어진 인증 레이어이다. OIDC의 핵심은 Identity provider를 보안적으로 안전하게 컨택해 유저를 인증하고, 유저 정보와 세션에 대한 정보를 획득하는 기능이다. SAML과 마찬가지로, OIDC는 web에서 많이 사용되고 있는 유저 인증 방식이다.

OIDC의 예시로는 쿠팡에 계정을 생성하는 과정을 생각해보자. 우리는 직접 아이디를 만들 수도 있지만, 카카오이나 네이버를 통해서도 계정을 생성할 수 있다. 카카오톡 혹은 네이버는 우리의 이름과 이메일 주소를 쿠팡에 전달하고, 쿠팡은 그 정보를 이용해 프로필을 생성한다. 우리는 전혀 비밀번호나 이름, 이메일 주소를 직접 보낼 필요가 없어진다.

OIDC의 이해

OIDC의 작동방식을 이해하려면, OAuth2에 대한 이해를 필요로 한다. OAuth2는 유저에게 유저가 가지고 있는 정보에 대해서 다른 어플리케이션에 비밀번호가 아닌 접근 토큰을 발행해 접근할 수 있도록 한다. 그러나, OAuth2 자체가 이러한 인증과 통제의 표준을 제공하는 것은 아니다.

OIDC는 여기에서, OAuth2를 사용하는 여러 파라미터를 모두 받아들이고, 표준화된 방식으로 인증 이벤트를 처리할 수 있도록 도와준다. JSON Web Token(이하 JWT)는 유저와 세션에 대한 정보를 담고 있고, 어플리케이션이 새로운 세션을 생성할 수 있도록 인증해준다. 결국, 유저는 하나의 인증 정보를 통해서 다수의 사이트와 어플리케이션의 인증을 처리할 수 있게 된다.

OIDC vs SAML

SAML은 웹-기반 클라이언트를 위해 디자인 된 상호간 보안증명 교환 프레임워크이다. SAML은 API 증명을 제공하지 않아서, 현재 web과 모바일 어플리케이션에서는 사용이 제한된다. OIDC는 API 기반(access token) 증명을 제공하므로 모바일과 웹 클라이언트 모두 백엔드 API에 전송할 수 있다. 따라서, 백엔드의 효율성이 증가한다. 따라서, 새롭게 만드는 서비스라면 OIDC가 권장된다고 할 수 있다.

OIDC 과정

OIDC는 ID와 비밀번호를 통해 권한을 제어하는 것이 아니라, 인증과 권한 부여를 OIDC token을 통해 수행한다. OIDC token은 유저의 정보를 담은 JWT로 인코딩된 토큰이다. JWT에는 온라인 자원에 인증할 수 있는 시간과, 유저 정보 등이 포함되어 있다. 이는 application이 읽어 유저가 인증되었음을 인식할 수 있게 되어 있다.

반면에 Access token은 보호된 자원들에 인가하는 용도로 만들어져 있다. 동일하게 JWT지만, ID token이 아니다. 이 token의 목적은 API에게 API 접근이 허락되었음을 알리는 용도이다.(특정 API에 대해서만 작동)

ID token은 API 접근 용도로 사용될 수 없고, API 토큰은 인증용으로 사용되지 않는 다는 것을 이해해야 한다. OIDC 토큰의 인증 프로세스 다이어그램은 다음과 같다.

OIDC token

OIDC는 ID token의 개념을 통해 OAuth2의 개념을 확장한다. ID token은 유저 이름, 이메일 등의 정보를 포함하여 JSON을 생성한다.

{
  iss: "https://my-domain.projects.oryapis.com",
  sub: "some-identity-id",
  aud: "some-client-id",
  exp: 1311281970,
  iat: 1311280970,
  nonce: "KxSty13b2L",
  // OpenID Connect standard claims:
  name: "Jane Doe",
  given_name: "Jane",
  family_name: "Doe",
  email: "jane@example.org",
  email_verified: true,
}

이는 access token과는 다른데, access token에서는 유저의 개인정보와 관련된 모든 정보를 포함시키지 않는다. 그래서 사용자 정보를 가져올려면 access token의 경우 access token 발급, access token으로 사용자 정보 요청 즉, 2번의 요청이 필요해서, ID token보다 2배의 통신이 필요하다.

{
  iss: "https://my-domain.projects.oryapis.com",
  sub: "some-identity-id",
  aud: "some-client-id",
  exp: 1311281970,
  iat: 1311280970,
  scope: "blog_posts photos",
}

ID token을 획득하기 위해서는 OpenID Provider(이하 OP)에 인증 요청을 보내야 한다. ID token은 표준 JWT 포맷으로 인코딩 된 뒤에, OP에 의해 사인된다.

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL215LWRvbWFpbi5wcm9qZWN0cy5vcnlhcGlzLmNvbSIsInN1YiI6InNvbWUtaWRlbnRpdHktaWQiLCJhdWQiOiJzb21lLWNsaWVudC1pZCIsImV4cCI6MTMxMTI4MTk3MCwiaWF0IjoxMzExMjgwOTcwLCJub25jZSI6Ikt4U3R5MTNiMkwiLCJuYW1lIjoiSmFuZSBEb2UiLCJnaXZlbl9uYW1lIjoiSmFuZSIsImZhbWlseV9uYW1lIjoiRG9lIiwiZW1haWwiOiJqYW5lQGV4YW1wbGUub3JnIiwiZW1haWxfdmVyaWZpZWQiOnRydWV9.50GMfrkHp1GcBdotJK6oirdr_bZUdJ1P5i4NlShOj2M

ID token은 이슈 발행 시각, 파기 시각 등이 정해져 있고, 디지털 사이닝(보증)이 되어 있어 다른 application으로 하여금 인증이 가능하도록 한다. 액세스 토큰은 여러 방식으로 획득할 수 있고, 인증과 관련해서 어떤 증명도 없다. 또한, 중요한 것은 ID token의 탈취 혹은 점유는 그 사람의 인증에 대한 완전한 증명이 된다. 이러한 token을 받은 application은 OP의 public key를 통해 decode를 진행한다. decode이후에도 안의 여러 요소를 검토해 유효성을 검증한다.

OIDC에 대한 이해를 통해, Keycloak이나 클라우드에서 사용하는 다양한 인증방식에 대한 이해를 높이고, 앞으로의 개발에서 유저 인증과 관련된 부분을 처리할 수 있을 것 같다.