TL;DR

  • SSO (Single Sign-On) 연동의 핵심 개념과 사용 범위를 한눈에 정리
  • 등장 배경과 필요한 이유를 짚고 실무 적용 포인트를 연결
  • 주요 특징과 체크리스트를 빠르게 확인

1. 개념

┌─────────────────────────────────────────────────────────────┐ │ │ │ SSO (Single Sign-On) = 단일 인증으로 여러 서비스 접근 │ │ │ │ 한 번 로그인하면... │ │ │ │ ┌─────────┐ ┌─────────────────────────────────────┐ │ │ │ 사용자 │────►│ Google/Okta/회사 포털 로그인 │ │ │ └─────────┘ └─────────────────────────────────────┘ │ │ │ │ │ │ │ ▼ │ │ │ ┌────────────────────────────────────┐ │ │ │ │ 토큰 발급 (JWT / SAML Assertion) │ │ │ │ └────────────────────────────────────┘ │ │ │ │ │ │ ▼ ▼ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ │ │ │ │ Gmail ✓ Drive ✓ YouTube ✓ Calendar ✓ │ │ │ │ │ │ │ │ (모든 서비스 추가 로그인 없이 접근 가능!) │ │ │ │ │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────┘

2. 배경

SSO (Single Sign-On) 연동이(가) 등장한 배경과 기존 한계를 정리한다.

3. 이유

이 주제를 이해하고 적용해야 하는 이유를 정리한다.

4. 특징

  • 1 SSO의 핵심 개념
  • 1 전체 흐름
  • 2 각 단계 설명
  • 1 개념
  • 2 구현 예시 (Python)

5. 상세 내용

작성일: 2026-01-29 카테고리: Backend / Security / Authentication 포함 내용: SSO, IdP, SP, OIDC, OAuth 2.0, SAML, JWT, JIT Provisioning, 인증/인가


1. SSO란?

┌─────────────────────────────────────────────────────────────┐
│                                                             │
│  SSO (Single Sign-On) = 단일 인증으로 여러 서비스 접근       │
│                                                             │
│  한 번 로그인하면...                                        │
│                                                             │
│  ┌─────────┐     ┌─────────────────────────────────────┐   │
│  │  사용자  │────►│  Google/Okta/회사 포털 로그인        │   │
│  └─────────┘     └─────────────────────────────────────┘   │
│       │                          │                          │
│       │                          ▼                          │
│       │         ┌────────────────────────────────────┐     │
│       │         │  토큰 발급 (JWT / SAML Assertion)   │     │
│       │         └────────────────────────────────────┘     │
│       │                          │                          │
│       ▼                          ▼                          │
│  ┌─────────────────────────────────────────────────────┐   │
│  │                                                     │   │
│  │   Gmail ✓    Drive ✓    YouTube ✓    Calendar ✓    │   │
│  │                                                     │   │
│  │   (모든 서비스 추가 로그인 없이 접근 가능!)          │   │
│  │                                                     │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
└─────────────────────────────────────────────────────────────┘

1.1 SSO의 핵심 개념

┌─────────────────────────────────────────────────────────────┐
│                                                             │
│  핵심 용어:                                                 │
│                                                             │
│  IdP (Identity Provider) = 인증 제공자                      │
│  ├── 사용자 인증을 담당                                     │
│  ├── 토큰/어설션 발급                                       │
│  └── 예: Google, Okta, Keycloak, Azure AD, 회사 LDAP        │
│                                                             │
│  SP (Service Provider) = 서비스 제공자                      │
│  ├── 실제 서비스를 운영                                     │
│  ├── IdP로부터 받은 토큰으로 사용자 확인                    │
│  └── 예: 우리가 만드는 애플리케이션                         │
│                                                             │
│  비유:                                                      │
│  ├── IdP = 여권 발급처 (정부)                               │
│  ├── SP = 공항/호텔 (여권으로 신원 확인)                    │
│  └── Token = 여권 (신뢰할 수 있는 신원 증명서)              │
│                                                             │
└─────────────────────────────────────────────────────────────┘

2. SSO 역사와 발전

┌─────────────────────────────────────────────────────────────┐
│                                                             │
│  1990년대: Kerberos                                         │
│  ├── MIT에서 개발                                           │
│  ├── 대칭키 기반 인증                                       │
│  └── 주로 사내 네트워크 (Windows AD 등)                     │
│                                                             │
│  2000년대: SAML (Security Assertion Markup Language)        │
│  ├── XML 기반 표준                                          │
│  ├── 엔터프라이즈 환경에서 널리 사용                        │
│  ├── 브라우저 기반 웹 SSO                                   │
│  └── 복잡하고 무거움                                        │
│                                                             │
│  2010년: OAuth 2.0                                          │
│  ├── "인가(Authorization)" 프레임워크                       │
│  ├── REST/JSON 기반으로 가벼움                              │
│  └── 단, 인증이 아닌 "위임" 목적                            │
│                                                             │
│  2014년: OIDC (OpenID Connect)                              │
│  ├── OAuth 2.0 위에 "인증(Authentication)" 레이어 추가      │
│  ├── ID Token (JWT) 도입                                    │
│  ├── 현대 SSO의 표준                                        │
│  └── Google, Facebook, Microsoft 등 모두 지원               │
│                                                             │
│  현재 트렌드:                                               │
│  ├── OIDC가 사실상 표준                                     │
│  ├── SAML은 레거시 엔터프라이즈에서만                       │
│  └── 패스키(Passkey), FIDO2 등 비밀번호 없는 미래           │
│                                                             │
└─────────────────────────────────────────────────────────────┘

3. OIDC 인증 플로우

3.1 전체 흐름

┌─────────────────────────────────────────────────────────────────────────┐
│                                                                         │
│   OIDC Authorization Code Flow (가장 안전하고 일반적인 방식)            │
│                                                                         │
│   ┌──────────┐      ┌──────────┐      ┌──────────┐      ┌──────────┐   │
│   │  사용자   │      │  브라우저 │      │  우리 서버 │      │   IdP    │   │
│   │  (User)  │      │ (Browser)│      │   (SP)   │      │ (Google) │   │
│   └────┬─────┘      └────┬─────┘      └────┬─────┘      └────┬─────┘   │
│        │                 │                 │                 │         │
│   1.   │ "Google 로그인" │                 │                 │         │
│        │────────────────►│                 │                 │         │
│        │                 │                 │                 │         │
│   2.   │                 │ /auth/google    │                 │         │
│        │                 │────────────────►│                 │         │
│        │                 │                 │                 │         │
│   3.   │                 │    302 Redirect to Google        │         │
│        │                 │◄────────────────│                 │         │
│        │                 │                 │                 │         │
│   4.   │                 │ accounts.google.com/authorize    │         │
│        │                 │────────────────────────────────────────────►│
│        │                 │                 │                 │         │
│   5.   │  Google 로그인 화면               │                 │         │
│        │◄────────────────│                 │                 │         │
│        │                 │                 │                 │         │
│   6.   │ ID/PW 입력      │                 │                 │         │
│        │────────────────►│                 │                 │         │
│        │                 │────────────────────────────────────────────►│
│        │                 │                 │                 │         │
│   7.   │                 │    302 + code=abc123             │         │
│        │                 │◄───────────────────────────────────────────│
│        │                 │                 │                 │         │
│   8.   │                 │ /callback?code= │                 │         │
│        │                 │────────────────►│                 │         │
│        │                 │                 │                 │         │
│   9.   │                 │                 │  POST /token    │         │
│        │                 │                 │  (code+secret)  │         │
│        │                 │                 │────────────────►│         │
│        │                 │                 │                 │         │
│  10.   │                 │                 │  access_token   │         │
│        │                 │                 │  + id_token     │         │
│        │                 │                 │◄────────────────│         │
│        │                 │                 │                 │         │
│  11.   │                 │  세션 생성 +    │                 │         │
│        │                 │  로그인 완료    │                 │         │
│        │                 │◄────────────────│                 │         │
│        │                 │                 │                 │         │
│        │  서비스 이용 가능                 │                 │         │
│        │◄────────────────│                 │                 │         │
│        │                 │                 │                 │         │
│   └────┴─────────────────┴─────────────────┴─────────────────┴─────┘   │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

3.2 각 단계 설명

┌─────────────────────────────────────────────────────────────┐
│                                                             │
│  1-3. 인증 요청 시작                                        │
│  ├── 사용자가 "Google로 로그인" 클릭                        │
│  ├── 서버가 Google 인증 URL로 리다이렉트                    │
│  └── URL에 client_id, redirect_uri, scope, state 포함      │
│                                                             │
│  4-6. IdP에서 인증                                          │
│  ├── 사용자가 Google 로그인 페이지 보임                     │
│  ├── ID/비밀번호 입력 (또는 기존 세션 사용)                 │
│  └── 동의 화면에서 권한 허용                                │
│                                                             │
│  7-8. Authorization Code 전달                               │
│  ├── Google이 code를 포함해 우리 서버로 리다이렉트          │
│  ├── code는 일회용, 짧은 유효기간                           │
│  └── state 값으로 CSRF 방지                                 │
│                                                             │
│  9-10. 토큰 교환 (Server-to-Server)                         │
│  ├── 서버가 code + client_secret으로 토큰 요청              │
│  ├── Google이 access_token + id_token 반환                  │
│  ├── id_token = JWT (사용자 정보 포함)                      │
│  └── 이 통신은 브라우저 거치지 않음 (안전!)                 │
│                                                             │
│  11. 로그인 완료                                            │
│  ├── id_token 검증 (서명, 발급자, 만료 등)                  │
│  ├── 사용자 정보 추출 (sub, email, name 등)                 │
│  ├── 우리 서버 세션 생성                                    │
│  └── 사용자에게 로그인 완료 응답                            │
│                                                             │
└─────────────────────────────────────────────────────────────┘

4. ID Token (JWT) 구조

┌─────────────────────────────────────────────────────────────┐
│                                                             │
│  ID Token = JWT (JSON Web Token)                            │
│                                                             │
│  구조: header.payload.signature                             │
│                                                             │
│  eyJhbGciOiJSUzI1NiJ9.                                     │
│  eyJzdWIiOiIxMjM0NTY3ODkwIiwiZW1haWwiOiJ1c2VyQGV4YW1wbGUuY29tIn0.│
│  signature_here                                             │
│                                                             │
│  ┌────────────────────────────────────────────────────┐    │
│  │  Payload (디코딩하면):                              │    │
│  │                                                    │    │
│  │  {                                                 │    │
│  │    "iss": "https://accounts.google.com",          │    │
│  │    "sub": "110248495921238986420",  ← 절대 변하지 않는 사용자 ID│
│  │    "aud": "your-client-id.apps.googleusercontent.com",│    │
│  │    "exp": 1706540400,              ← 만료 시간     │    │
│  │    "iat": 1706536800,              ← 발급 시간     │    │
│  │    "email": "user@gmail.com",      ← 이메일        │    │
│  │    "email_verified": true,                         │    │
│  │    "name": "김개발",                ← 이름         │    │
│  │    "picture": "https://..."        ← 프로필 사진   │    │
│  │  }                                                 │    │
│  │                                                    │    │
│  └────────────────────────────────────────────────────┘    │
│                                                             │
│  핵심 클레임:                                               │
│  ├── sub (Subject): 절대 변하지 않는 사용자 고유 ID         │
│  ├── iss (Issuer): 토큰 발급자 (Google, Okta 등)            │
│  ├── aud (Audience): 이 토큰의 대상 (우리 client_id)        │
│  ├── exp (Expiration): 만료 시간                            │
│  └── email, name 등: 사용자 프로필 정보                     │
│                                                             │
└─────────────────────────────────────────────────────────────┘

5. JIT Provisioning (자동 계정 생성)

5.1 개념

┌─────────────────────────────────────────────────────────────┐
│                                                             │
│  JIT (Just-In-Time) Provisioning                            │
│                                                             │
│  = SSO 로그인 시점에 자동으로 로컬 계정을 생성              │
│                                                             │
│  ┌────────────────────────────────────────────────────┐    │
│  │                                                    │    │
│  │  1. 사용자가 처음 SSO 로그인                       │    │
│  │                                                    │    │
│  │  2. 우리 서버: "이 sub으로 등록된 사용자가 있나?"  │    │
│  │                                                    │    │
│  │  3. 없으면 → 자동으로 계정 생성! (JIT)            │    │
│  │     - sso_provider: "google"                       │    │
│  │     - sso_subject_id: "110248495921238986420"      │    │
│  │     - email: "user@gmail.com"                      │    │
│  │     - name: "김개발"                               │    │
│  │                                                    │    │
│  │  4. 있으면 → 기존 계정으로 로그인                  │    │
│  │                                                    │    │
│  └────────────────────────────────────────────────────┘    │
│                                                             │
│  장점:                                                      │
│  ├── 관리자가 미리 계정 생성할 필요 없음                    │
│  ├── 사용자 경험 매끄러움 (한 번 클릭으로 가입+로그인)      │
│  └── IdP의 사용자 정보와 항상 동기화                        │
│                                                             │
└─────────────────────────────────────────────────────────────┘

5.2 구현 예시 (Python)

async def get_or_create_user(id_token: str) -> User:
    """
    SSO 로그인 시 사용자 조회 또는 자동 생성 (JIT Provisioning)
    """
    # 1. ID Token 검증 및 디코딩
    payload = jwt.decode(
        id_token,
        key=IDP_PUBLIC_KEY,
        algorithms=["RS256"],
        audience=CLIENT_ID,
        issuer="https://accounts.google.com"
    )

    # 2. 핵심 정보 추출
    sso_subject_id = payload["sub"]      # 절대 변하지 않는 ID!
    email = payload.get("email")
    name = payload.get("name")

    # 3. 기존 사용자 조회 (sub 기준!)
    #    ⚠️ email이 아닌 sub으로 조회해야 함 (이메일은 변할 수 있음)
    user = await db.users.find_one({"sso_subject_id": sso_subject_id})

    # 4. 없으면 JIT Provisioning (자동 생성)
    if not user:
        user = await db.users.insert_one({
            "sso_provider": "google",
            "sso_subject_id": sso_subject_id,
            "email": email,
            "name": name,
            "created_at": datetime.now(),
            "role": "user"       # 기본 권한
        })
        logger.info(f"New user created via SSO: {email}")
    else:
        # 기존 사용자면 프로필 정보 업데이트 (선택적)
        await db.users.update_one(
            {"_id": user["_id"]},
            {"$set": {"email": email, "name": name, "last_login": datetime.now()}}
        )

    return user

5.3 DB 스키마 예시

-- SSO 연동 시 사용자 테이블 구조
CREATE TABLE users (
    id              SERIAL PRIMARY KEY,

    -- SSO 관련 필드 (핵심!)
    sso_provider    VARCHAR(50),     -- 'google', 'okta', 'azure' 등
    sso_subject_id  VARCHAR(255),    -- IdP에서 발급한 고유 ID (sub)

    -- 프로필 정보 (IdP에서 가져옴)
    email           VARCHAR(255),
    name            VARCHAR(255),
    picture_url     VARCHAR(500),

    -- 앱 자체 데이터
    role            VARCHAR(50) DEFAULT 'user',
    created_at      TIMESTAMP DEFAULT NOW(),
    last_login      TIMESTAMP,

    -- 유니크 제약: 같은 IdP에서 같은 subject_id 중복 불가
    UNIQUE(sso_provider, sso_subject_id)
);

-- ❌ password 컬럼 없음!
-- ❌ password_hash 컬럼 없음!

6. SSO 보안 이점

6.1 서버에 저장되지 않는 것들

┌─────────────────────────────────────────────────────────────┐
│                                                             │
│  SSO 사용 시 우리 서버에 없는 것:                           │
│                                                             │
│  ❌ 비밀번호 (password)                                     │
│  ❌ 비밀번호 해시 (bcrypt, argon2 등)                       │
│  ❌ 비밀번호 salt                                           │
│  ❌ 비밀번호 재설정 토큰                                    │
│  ❌ 보안 질문/답변                                          │
│                                                             │
│  비밀번호는 IdP (Google, Okta 등)만 가지고 있음!            │
│                                                             │
└─────────────────────────────────────────────────────────────┘

6.2 Credential Stuffing 방어

┌─────────────────────────────────────────────────────────────┐
│                                                             │
│  Credential Stuffing Attack (크리덴셜 스터핑)               │
│                                                             │
│  = 다른 사이트에서 유출된 ID/PW로 로그인 시도               │
│                                                             │
│  ┌─────────────────────────────────────────────────────┐   │
│  │                                                     │   │
│  │  해커의 공격 시나리오:                              │   │
│  │                                                     │   │
│  │  1. 사이트 A 털림 → 1천만 개 ID/PW 유출            │   │
│  │                                                     │   │
│  │  2. 해커: "사람들은 여러 사이트에 같은 비번 쓰지!"  │   │
│  │                                                     │   │
│  │  3. 유출된 ID/PW로 사이트 B, C, D 로그인 시도       │   │
│  │                                                     │   │
│  │  4. 상당수 성공! (비번 재사용 때문)                 │   │
│  │                                                     │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  SSO 사용 시:                                               │
│                                                             │
│  ┌─────────────────────────────────────────────────────┐   │
│  │                                                     │   │
│  │  해커가 우리 서버를 털어도...                       │   │
│  │                                                     │   │
│  │  - 비밀번호 없음 ← 시도할 수 없음!                  │   │
│  │  - 다른 사이트 공격 불가                            │   │
│  │  - Credential Stuffing 원천 차단                    │   │
│  │                                                     │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
└─────────────────────────────────────────────────────────────┘

6.3 서버가 털렸을 때 비교

┌─────────────────────────────────────────────────────────────┐
│                                                             │
│  🔓 전통적 방식 (자체 인증) - 서버 침해 시                  │
│                                                             │
│  유출 가능:                                                 │
│  ├── 비밀번호 해시 (레인보우 테이블/무차별 대입 위험)       │
│  ├── 이메일, 개인정보                                       │
│  ├── 세션 토큰                                              │
│  └── 모든 사용자 데이터                                     │
│                                                             │
│  피해:                                                      │
│  ├── 비밀번호 크래킹 시도 가능                              │
│  ├── 다른 사이트 공격 (크리덴셜 스터핑)                     │
│  └── 계정 탈취                                              │
│                                                             │
│  ─────────────────────────────────────────────────────────  │
│                                                             │
│  🔐 SSO 방식 - 서버 침해 시                                 │
│                                                             │
│  유출 가능:                                                 │
│  ├── sso_subject_id (무의미한 ID 문자열)                    │
│  ├── 이메일, 개인정보                                       │
│  ├── 세션 토큰 (아직 유효하다면)                            │
│  └── 사용자 데이터                                          │
│                                                             │
│  유출 불가능:                                               │
│  ├── ❌ 비밀번호 (없음!)                                    │
│  └── ❌ IdP 인증 정보                                       │
│                                                             │
│  결과:                                                      │
│  ├── 비밀번호 크래킹 불가 (애초에 없음)                     │
│  ├── 다른 사이트 공격 불가                                  │
│  └── 계정 탈취는 여전히 위험 (세션 토큰)                    │
│                                                             │
└─────────────────────────────────────────────────────────────┘

6.4 여전히 주의할 점

┌─────────────────────────────────────────────────────────────┐
│                                                             │
│  ⚠️ SSO를 써도 여전히 보호해야 할 것들:                     │
│                                                             │
│  1. 세션 토큰                                               │
│     └── 탈취 시 해당 세션으로 로그인 가능                   │
│     └── 대책: 짧은 만료 시간, IP 바인딩, 디바이스 핑거프린팅│
│                                                             │
│  2. 개인정보 (이메일, 이름 등)                              │
│     └── 개인정보보호법 위반 가능                            │
│     └── 대책: 암호화 저장, 최소 수집 원칙                   │
│                                                             │
│  3. 앱 자체 데이터 (결제 정보, 문서 등)                     │
│     └── 비즈니스 핵심 자산                                  │
│     └── 대책: 별도 암호화, 접근 제어                        │
│                                                             │
│  4. ID Token / Refresh Token (저장한다면)                   │
│     └── 탈취 시 IdP API 호출 가능                           │
│     └── 대책: 암호화 저장 또는 저장 안 함                   │
│                                                             │
└─────────────────────────────────────────────────────────────┘

7. 프로토콜 비교: SAML vs OAuth 2.0 vs OIDC

┌──────────────────────────────────────────────────────────────────────────┐
│                                                                          │
│  ┌──────────┬────────────────┬────────────────┬────────────────┐        │
│  │          │     SAML       │   OAuth 2.0    │     OIDC       │        │
│  ├──────────┼────────────────┼────────────────┼────────────────┤        │
│  │ 목적     │ 인증 + 인가    │ 인가 (위임)    │ 인증 + 인가    │        │
│  ├──────────┼────────────────┼────────────────┼────────────────┤        │
│  │ 포맷     │ XML            │ JSON           │ JSON + JWT     │        │
│  ├──────────┼────────────────┼────────────────┼────────────────┤        │
│  │ 토큰     │ SAML Assertion │ Access Token   │ ID Token (JWT) │        │
│  │          │                │                │ + Access Token │        │
│  ├──────────┼────────────────┼────────────────┼────────────────┤        │
│  │ 복잡도   │ 높음 (무거움)  │ 중간           │ 중간           │        │
│  ├──────────┼────────────────┼────────────────┼────────────────┤        │
│  │ 사용처   │ 엔터프라이즈   │ API 권한 위임  │ 웹/모바일 SSO  │        │
│  │          │ 레거시 시스템  │ "~로 로그인"   │ 현대 앱 표준   │        │
│  ├──────────┼────────────────┼────────────────┼────────────────┤        │
│  │ 예시     │ 사내 시스템    │ "앱이 내 Google│ Google 로그인  │        │
│  │          │ 정부 시스템    │  드라이브 접근 │ Facebook 로그인│        │
│  │          │                │  허용"         │                │        │
│  └──────────┴────────────────┴────────────────┴────────────────┘        │
│                                                                          │
│  현재 권장:                                                              │
│  ├── 새 프로젝트 → OIDC                                                 │
│  ├── API 권한 위임 → OAuth 2.0                                          │
│  └── 레거시 연동 → SAML (어쩔 수 없이)                                  │
│                                                                          │
└──────────────────────────────────────────────────────────────────────────┘

8. OAuth vs OIDC 차이

┌─────────────────────────────────────────────────────────────┐
│                                                             │
│  OAuth 2.0 = "인가 (Authorization)"                         │
│  "이 앱이 내 리소스에 접근해도 돼요"                        │
│                                                             │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  예: "이 앱이 내 Google 드라이브 읽기 허용"         │   │
│  │                                                     │   │
│  │  - Access Token 발급                                │   │
│  │  - 사용자가 "누구인지"는 표준화 안 됨!              │   │
│  │  - API 호출 권한만 부여                             │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  ─────────────────────────────────────────────────────────  │
│                                                             │
│  OIDC = OAuth 2.0 + "인증 (Authentication)"                 │
│  "이 사용자가 누구인지 증명"                                │
│                                                             │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  예: "Google로 로그인"                              │   │
│  │                                                     │   │
│  │  - ID Token (JWT) 추가 발급                         │   │
│  │  - 사용자 정보가 토큰에 포함 (sub, email, name)     │   │
│  │  - 표준화된 사용자 정보 엔드포인트 (/userinfo)      │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  비유:                                                      │
│  ├── OAuth = 열쇠 (방에 들어갈 권한)                        │
│  └── OIDC = 열쇠 + 신분증 (누가 들어가는지도 알 수 있음)   │
│                                                             │
└─────────────────────────────────────────────────────────────┘

9. 실제 구현 체크리스트

┌─────────────────────────────────────────────────────────────┐
│                                                             │
│  SSO 연동 시 체크리스트:                                    │
│                                                             │
│  □ IdP 설정                                                 │
│    ├── Client ID 발급                                       │
│    ├── Client Secret 발급 (안전하게 보관!)                  │
│    ├── Redirect URI 등록                                    │
│    └── 요청할 Scope 설정 (openid, email, profile 등)        │
│                                                             │
│  □ 인증 플로우 구현                                         │
│    ├── /auth/login → IdP로 리다이렉트                       │
│    ├── /auth/callback → code 받아서 토큰 교환               │
│    ├── state 파라미터로 CSRF 방지                           │
│    └── nonce로 리플레이 공격 방지                           │
│                                                             │
│  □ 토큰 검증                                                │
│    ├── 서명 검증 (IdP 공개키로)                             │
│    ├── iss (발급자) 확인                                    │
│    ├── aud (대상) 확인 (우리 client_id와 일치)              │
│    ├── exp (만료) 확인                                      │
│    └── nonce 확인 (사용했다면)                              │
│                                                             │
│  □ 사용자 관리                                              │
│    ├── sub 기준으로 사용자 조회/생성 (email 아님!)          │
│    ├── JIT Provisioning 구현                                │
│    └── 프로필 정보 동기화 정책 결정                         │
│                                                             │
│  □ 보안                                                     │
│    ├── HTTPS 필수                                           │
│    ├── Client Secret 안전하게 보관 (환경변수, Vault 등)     │
│    ├── 세션 관리 (만료, 갱신, 무효화)                       │
│    └── 로그아웃 시 IdP 로그아웃도 고려                      │
│                                                             │
└─────────────────────────────────────────────────────────────┘

10. 정리

┌─────────────────────────────────────────────────────────────┐
│                                                             │
│  SSO 핵심 요약:                                             │
│                                                             │
│  1. SSO = 한 번 로그인으로 여러 서비스 이용                 │
│                                                             │
│  2. IdP(인증) ↔ SP(서비스) 구조                             │
│                                                             │
│  3. 현대 표준 = OIDC (OAuth 2.0 + 인증 레이어)              │
│                                                             │
│  4. JIT Provisioning = 첫 로그인 시 자동 계정 생성          │
│                                                             │
│  5. 보안 이점:                                              │
│     ├── 비밀번호 저장 안 함 → 크리덴셜 스터핑 방어          │
│     ├── IdP의 강력한 보안 (MFA, 이상 탐지 등) 활용          │
│     └── 단일 인증 지점 → 보안 관리 용이                     │
│                                                             │
│  6. 여전히 보호 필요: 세션, 개인정보, 앱 데이터             │
│                                                             │
│  7. sub으로 사용자 식별 (email은 변할 수 있음!)             │
│                                                             │
└─────────────────────────────────────────────────────────────┘

관련 키워드

SSO, Single Sign-On, IdP, SP, OIDC, OpenID Connect, OAuth 2.0, SAML, JWT, ID Token, JIT Provisioning, 인증, 인가, Authorization Code Flow, sub, Credential Stuffing