OpenID

OpenID는 사용자가 여러 웹사이트와 애플리케이션에 단일 자격 증명으로 로그인할 수 있게 해주는 분산형 인증 표준이다. 이 기술은 디지털 신원 관리 방식을 근본적으로 변화시켰으며, 현대 웹의 인증 체계에 중요한 역할을 하고 있다.

OpenID의 기본 개념

OpenID는 2005년에 처음 도입되었으며, 사용자가 여러 서비스에서 동일한 디지털 신원을 사용할 수 있도록 하는 것이 목표였다.
기본적인 아이디어는 간단하다: 사용자는 자신이 신뢰하는 제3자 서비스(IdP, Identity Provider)를 통해 인증하고, 이 인증 정보를 다른 웹사이트와 애플리케이션(RP, Relying Party)에서 사용한다.

이것은 마치 여러 건물에 출입할 때 매번 다른 신분증을 제시하는 대신, 하나의 신뢰할 수 있는 신분증으로 여러 장소에 접근하는 것과 유사하다.

OpenID의 작동 방식

OpenID 인증 과정은 다음과 같은 단계로 진행된다:

  1. 사용자 요청: 사용자가 서비스(RP)에 접속하여 OpenID 로그인을 선택한다.
  2. 리다이렉션: 서비스는 사용자를 선택한 ID 제공자(IdP)로 리다이렉트한다.
  3. 인증: 사용자는 ID 제공자에서 자신의 신원을 증명한다(예: 비밀번호 입력).
  4. 승인: 인증이 성공하면, 사용자는 서비스에 자신의 정보 공유를 승인한다.
  5. 토큰 발급: ID 제공자는 인증 토큰을 생성하여 서비스에 전달한다.
  6. 검증 및 로그인: 서비스는 토큰을 검증하고 사용자 로그인을 완료한다.

OpenID Connect(OIDC)

OpenID의 최신 버전인 OpenID Connect는 OAuth 2.0 프로토콜 위에 구축된 인증 레이어이다. OIDC는 2014년에 공식 릴리스되었으며, 다음과 같은 주요 특징을 제공한다:

  1. ID 토큰: JWT(JSON Web Token) 형식으로 사용자 신원 정보를 안전하게 전달한다.
  2. UserInfo 엔드포인트: 추가적인 사용자 정보를 요청할 수 있는 표준화된 API를 제공한다.
  3. 표준 클레임: 이름, 이메일, 프로필 사진 등 사용자 정보에 대한 표준화된 필드를 정의한다.
  4. 다양한 인증 플로우: 웹 애플리케이션, 모바일 앱, 싱글 페이지 애플리케이션 등 다양한 시나리오에 적합한 인증 흐름을 지원한다.

OAuth 2.0과의 관계

OpenID Connect와 OAuth 2.0은 밀접하게 연관되어 있지만, 다른 목적을 가지고 있다:

간단히 말해, “내가 누구인지"를 확인하는 것은 OpenID Connect이고, “내 데이터에 무엇을 할 수 있는지"를 결정하는 것은 OAuth 2.0입니다.

OIDC의 주요 구성 요소

OpenID Connect 시스템은 다음과 같은 주요 구성 요소로 이루어져 있다:

  1. ID 제공자(IdP): 사용자 인증을 처리하고 ID 토큰을 발급한다. (예: Google, Facebook, Microsoft)
  2. 서비스 제공자(RP): 사용자 인증을 ID 제공자에게 위임하는, OpenID를 사용하는 애플리케이션이다.
  3. 최종 사용자: 서비스에 접근하려는 개인이다.
  4. ID 토큰: 사용자 신원 정보를 포함한 JWT 형식의 토큰이다.
  5. 액세스 토큰: 보호된 리소스에 접근할 수 있는 권한을 나타내는 토큰이다.
  6. 권한 부여 서버: OAuth 2.0 흐름을 처리하고 토큰을 발급하는 서버이다.

코드 예제: Python에서 OpenID Connect 클라이언트 구현

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# OIDC 클라이언트 구현 예제 (Python)
from authlib.integrations.flask_client import OAuth
from flask import Flask, url_for, redirect, session

app = Flask(__name__)
app.secret_key = '랜덤한_비밀_키'

oauth = OAuth(app)
oauth.register(
    name='google',  # ID 제공자 이름
    server_metadata_url='https://accounts.google.com/.well-known/openid-configuration',  # 메타데이터 URL
    client_id='YOUR_CLIENT_ID',  # 클라이언트 ID
    client_secret='YOUR_CLIENT_SECRET',  # 클라이언트 비밀키
    client_kwargs={
        'scope': 'openid email profile'  # 요청할 범위
    }
)

@app.route('/')
def homepage():
    user = session.get('user')
    if user:
        return f'안녕하세요, {user["name"]}님!'
    return '<a href="/login">Google 로그인</a>'

@app.route('/login')
def login():
    # 사용자를 Google 로그인 페이지로 리다이렉트
    redirect_uri = url_for('auth', _external=True)
    return oauth.google.authorize_redirect(redirect_uri)

@app.route('/auth')
def auth():
    # Google로부터 인증 응답 처리
    token = oauth.google.authorize_access_token()
    # UserInfo 엔드포인트에서 사용자 정보 가져오기
    user_info = oauth.google.parse_id_token(token)
    session['user'] = user_info
    return redirect('/')

if __name__ == '__main__':
    app.run(debug=True)

이 코드는 Flask 웹 애플리케이션에서 Google을 ID 제공자로 사용하는 OpenID Connect 인증을 구현한 예이다. 사용자가 ‘/login’ 경로에 접속하면 Google 로그인 페이지로 리다이렉트되고, 인증 후에는 ‘/auth’ 경로에서 ID 토큰을 처리하여 사용자 정보를 세션에 저장한다.

OpenID의 장점

  1. 사용자 경험 향상: 사용자는 여러 서비스에 동일한 자격 증명으로 로그인할 수 있어 편리하다.
  2. 보안 강화: 자격 증명은 전문적인 ID 제공자가 관리하므로 보안 수준이 높아진다.
  3. 개발 간소화: 개발자는 복잡한 인증 시스템을 직접 구현할 필요 없이 표준 프로토콜을 사용할 수 있다.
  4. 중앙화된 계정 관리: 사용자는 하나의 계정만 관리하면 되므로 패스워드 피로를 줄일 수 있다.
  5. 표준화된 접근 방식: 업계 표준을 따르므로 호환성과 상호 운용성이 높다.

OpenID의 도전과제

  1. 개인정보 보호: 중앙화된 ID 제공자는 사용자의 로그인 활동에 대한 많은 정보를 수집할 수 있다.
  2. 의존성 문제: ID 제공자 서비스가 중단되면 모든 연결된 서비스에 로그인할 수 없게 된다.
  3. 구현 복잡성: 완전한 OIDC 지원을 구현하는 것은 간단한 사용자명/비밀번호 인증보다 복잡할 수 있다.
  4. 사용자 교육: 많은 사용자들이 아직 SSO(Single Sign-On) 개념을 완전히 이해하지 못한다.

용어 정리

용어설명

참고 및 출처