1. Important Points#

SSO 是目标,不是某一个具体产品或协议。公司想解决的是“员工只用一个身份登录多个系统”,背后通常会同时出现 IdP、SAML、OIDC、OAuth2、JWT、SCIM 这些概念。

business goal:
    one employee identity
    one login entry
    consistent MFA policy
    centralized joiner / mover / leaver process
    less manual account creation in every system

technical pieces:
    IdP stores and verifies user identity
    LDAP / AD can store users, groups, passwords, and directory attributes
    SAML or OIDC carries login result to applications
    OAuth2 grants API access
    JWT carries claims for modern apps
    SCIM provisions and disables accounts

核心判断:

SSO:
    解决统一登录

SCIM / provisioning:
    解决自动创建、同步、禁用账号

RBAC / app authorization:
    解决登录后在系统里能做什么

MFA / device policy:
    解决登录风险控制

不要把这些混在一起。一个系统支持 SAML SSO,不代表它支持自动创建账号;支持自动创建账号,也不代表权限模型已经设计好了。

2. Mental Model#

最简单的模型:

employee
    -> login at IdP
        -> IdP proves who the employee is
            -> app receives signed login result
                -> app creates session
                    -> app checks local role / group / permission

公司统一认证的常见架构:

Microsoft Entra ID / Okta / Google Workspace / ADFS
    -> SAML / OIDC
        -> SaaS apps
        -> internal apps
        -> AWS IAM Identity Center
        -> Amazon Cognito User Pool

如果公司已有 LDAP / Active Directory,常见做法不是让应用直接都接 LDAP,而是在目录服务前面放一层 SSO / IdP:

LDAP / Active Directory
    -> Keycloak / AD FS / Entra ID / Okta
        -> SAML / OIDC
            -> SaaS apps
            -> internal apps
            -> APIs

这层的意义不是简单“套壳”,而是把 directory authentication 转成现代 SSO protocol:

LDAP / AD:
    bind / search / group lookup
    stores users, groups, passwords, directory attributes

SSO IdP layer:
    browser redirect flow
    SSO session
    MFA / authentication policy
    signed SAML assertion
    OIDC discovery / token endpoint / JWKS
    JWT / claim / attribute mapping

如果有自研业务系统,常见做法是:

company IdP
    -> SAML or OIDC
        -> Cognito User Pool
            -> OIDC / OAuth2 JWT
                -> web app / mobile app / backend API

这里 Cognito 的位置比较特殊:

upstream:
    Cognito 可以接公司 IdP,比如 SAML IdP 或 OIDC IdP

downstream:
    Cognito 又可以作为 OIDC provider 给你的应用发 JWT

所以 Cognito 可以用来统一自研应用的登录入口,但它通常不是整个公司的 HR / workforce identity 主系统。

3. Glossary#

Term Full Name Meaning Think Of It As
SSO Single Sign-On 一次登录,访问多个系统 目标 / 体验
IdP Identity Provider 负责认证用户身份的系统 公司身份源
SP Service Provider 接收 SAML 登录结果的应用 被登录的系统
RP Relying Party OIDC 里的应用方 OIDC 版 SP
SAML Security Assertion Markup Language 老牌企业 SSO 协议 XML 登录票据
OIDC OpenID Connect 基于 OAuth2 的现代登录协议 JSON / JWT 登录协议
OAuth2 OAuth 2.0 授权框架,不是单独的登录协议 允许 app 调 API
JWT JSON Web Token 带签名的 JSON token 登录/权限声明包
LDAP Lightweight Directory Access Protocol 目录访问协议 查用户/组、验证密码
AD DS Active Directory Domain Services Microsoft 目录服务 LDAP/Kerberos/域账号
AD FS Active Directory Federation Services Microsoft federation service 给 AD 增加 SAML/OIDC 层
Directory Directory Service 用户、组、组织属性的目录源 身份数据仓库
Claim Claim token/assertion 里的字段 email, name, group
Scope OAuth scope API 权限范围 orders/read
MFA Multi-Factor Authentication 多因素认证 密码之外再验证
SCIM System for Cross-domain Identity Management 用户和组同步协议 自动开户/禁用
JIT Just-In-Time provisioning 第一次 SSO 登录时创建本地账号 登录时开户
ACS URL Assertion Consumer Service URL SAML 登录结果回调地址 SAML callback
Redirect URI Redirect URI OIDC/OAuth 登录回调地址 OIDC callback
Metadata SAML metadata SAML IdP/SP 的证书和端点信息 双方交换配置
JWKS JSON Web Key Set 用来验证 JWT 签名的公钥集合 token 验签公钥

4. SSO#

SSO 说的是使用体验和账号治理目标:

before:
    GitLab has one password
    Jira has one password
    Grafana has one password
    internal admin has one password
    AWS console has IAM users

after:
    employee logs in with company identity
    each system trusts the company IdP
    MFA policy is centralized
    leaving employee can be disabled centrally

SSO 本身不是协议。实现 SSO 可以用:

SAML:
    common for enterprise SaaS and older internal systems

OIDC:
    common for modern web apps, mobile apps, APIs, and developer-built apps

proprietary agent / LDAP / Kerberos:
    possible in older enterprise environments
    LDAP itself is directory access, not a modern browser SSO protocol

5. IdP and SP#

IdP 是身份提供方。它负责确认“这个人是谁”。

examples:
    Microsoft Entra ID
    Okta
    Google Workspace
    OneLogin
    Ping Identity
    ADFS
    AWS IAM Identity Center internal identity store
    Amazon Cognito User Pool, for app users

SP 是服务提供方。它不自己维护员工密码,而是信任 IdP 的登录结果。

examples:
    GitLab
    Jira
    Confluence
    Grafana
    AWS IAM Identity Center
    internal admin system
    payroll system

SAML 里通常叫:

IdP:
    identity provider

SP:
    service provider

OIDC 里通常叫:

OP:
    OpenID Provider, 发 token 的身份系统

RP:
    Relying Party, 使用 token 的应用

日常沟通里可以简化成:

IdP:
    登录中心

App / SP / RP:
    需要登录的业务系统

Directory vs IdP protocol layer#

LDAP / AD 和 SAML / OIDC 不是同一层东西。

LDAP / AD DS:
    directory layer
    stores users, groups, passwords, organization attributes
    supports bind, search, group lookup
    often also works with Kerberos in Windows domain environments

SAML / OIDC IdP:
    web SSO protocol layer
    handles browser redirect login
    creates SSO session
    signs SAML assertion or JWT
    publishes metadata / discovery / JWKS
    validates client redirect URI or SAML ACS URL

所以如果一个系统只支持 LDAP auth,它通常是在登录时直接拿用户名密码去目录里验证:

app
    -> LDAP bind/search
        -> LDAP / AD DS

如果一个系统支持 SAML / OIDC,它通常不直接看用户密码,而是信任 IdP 发来的签名登录结果:

app
    -> redirects user to IdP
        -> IdP authenticates user through local DB / LDAP / AD / upstream IdP
            -> app receives signed SAML assertion or OIDC token

Keycloak 在这里通常是协议层和策略层,不是 LDAP server:

LDAP / AD DS:
    source of users, groups, passwords

Keycloak:
    connects to LDAP / AD through User Federation
    maps LDAP users / groups / attributes
    adds SSO session, MFA, flows, clients, protocol mappers
    issues OIDC tokens or SAML assertions to apps

这不是纯粹套壳,因为 Keycloak 还负责 client 管理、redirect URI / ACS URL 校验、token 签名、session、MFA、claim mapping、logout 等 SSO 能力。

AD 相关组件要分开看:

AD DS:
    directory service
    LDAP / Kerberos / domain account

AD FS:
    federation service
    SAML / WS-Fed / OIDC layer in front of AD

Microsoft Entra ID:
    cloud IdP
    modern workforce SSO / app federation / conditional access

判断方式:

if app only supports LDAP:
    app can authenticate directly against LDAP / AD DS

if app needs SAML / OIDC:
    use Keycloak / AD FS / Okta / Entra ID / similar IdP

if company already has LDAP / AD:
    keep it as directory source
    put an IdP layer in front for modern SSO

6. SAML#

SAML 是企业 SSO 里非常常见的协议,很多传统 SaaS 和企业软件都支持。

main use:
    browser-based employee login
    enterprise SaaS SSO
    legacy internal apps
    AWS IAM Identity Center external IdP integration

典型流程:

1. user opens app
2. app redirects browser to IdP
3. user logs in at IdP and passes MFA
4. IdP posts signed SAML assertion back to app ACS URL
5. app verifies signature and creates local session

SAML assertion 里通常会有:

NameID:
    user identifier

email:
    user email

displayName:
    human-readable name

groups:
    group membership, if mapped

department / title:
    optional HR attributes

适合:

enterprise SaaS:
    Jira, Confluence, GitLab, Slack, Salesforce, old admin tools

employee workforce SSO:
    company employees logging into company systems

systems that only support SAML:
    many older products support SAML before they support OIDC

不适合:

mobile native login:
    OIDC is usually better

API authorization:
    OAuth2 access token is usually better

fine-grained API scopes:
    SAML is not designed for that

7. OIDC#

OIDC 是 OpenID Connect。它建立在 OAuth2 上,用 JSON 和 JWT 表达登录结果,是现代应用最常用的登录协议。

main use:
    web app login
    SPA login
    mobile app login
    backend API receives bearer token
    Cognito / Auth0 / Okta / Entra ID app integration

典型流程:

1. app redirects browser to authorization endpoint
2. user logs in at IdP
3. IdP redirects back to app redirect_uri with authorization code
4. app exchanges code for tokens
5. app receives ID token, access token, and maybe refresh token
6. backend verifies access token before serving API requests

常见 token:

ID token:
    proves user identity
    consumed by client app
    contains identity claims such as sub, email, name

Access token:
    authorizes API access
    consumed by backend API
    contains scope, client_id, groups, token_use

Refresh token:
    used to obtain new ID/access tokens
    stored carefully

适合:

new internal apps:
    use OIDC if app supports it

custom web/mobile apps:
    use Authorization Code + PKCE

API-centric architecture:
    backend can verify JWT locally

machine-to-machine:
    use OAuth2 client credentials, not user login

不适合:

SaaS only supports SAML:
    use SAML

old app only understands headers/session:
    use reverse proxy or ALB auth pattern

want automatic employee lifecycle:
    OIDC alone is not enough; add SCIM/provisioning

8. OAuth2#

OAuth2 经常和 OIDC 混在一起,但它们不是一回事。

OAuth2:
    authorization framework
    answers: can this client access this resource?

OIDC:
    identity layer on top of OAuth2
    answers: who is this user?

简单理解:

login:
    use OIDC

API permission:
    use OAuth2 access token and scopes

machine-to-machine:
    use OAuth2 client credentials

常见 grant:

Grant Use Case Recommendation
Authorization Code + PKCE browser/mobile user login default for modern apps
Client Credentials service-to-service default for M2M
Refresh Token renew user session use with rotation/revocation
Implicit old browser apps avoid for new apps
Password Grant app collects user password avoid

9. SAML vs OIDC#

Decision Choose SAML Choose OIDC
SaaS integration Very common Use if SaaS supports it well
Legacy enterprise app Usually better Often unsupported
New custom app Usually not first choice Usually best default
Mobile app Not ideal Best default
SPA Possible but clunky Authorization Code + PKCE
API authorization Not ideal Access token + scopes
Token format XML assertion JSON / JWT
Metadata SAML metadata XML OIDC discovery + JWKS
Callback ACS URL redirect_uri
User provisioning Not built in Not built in

Practical rule:

third-party SaaS:
    use SAML unless the vendor's OIDC support is clearly better

new internal web/app/API:
    use OIDC

AWS console and AWS account access:
    use IAM Identity Center

custom app already using Cognito:
    federate Cognito to company IdP with SAML or OIDC

10. Cognito, IAM Identity Center, and Company IdP#

这几个东西容易混:

Component Best For Not Best For
Company IdP 员工主身份源、MFA、组、生命周期 业务应用数据库
AWS IAM Identity Center AWS account access, permission sets, workforce access to AWS 自研 App 用户认证主入口
Amazon Cognito User Pool 自研 App 登录、JWT、用户池、社交/OIDC/SAML federation 公司全员 HR 身份治理
Amazon Cognito Identity Pool 把用户身份换成临时 AWS credentials 普通 Web API 登录
AWS IAM AWS API 权限控制 员工 SSO 登录入口

推荐分工:

employee identity source:
    Microsoft Entra ID / Okta / Google Workspace / ADFS

AWS console access:
    IAM Identity Center

self-built apps:
    Cognito User Pool or direct OIDC/SAML integration to company IdP

browser/mobile app token issuer:
    Cognito User Pool is a good choice

direct client access to S3/AppSync/etc:
    Cognito Identity Pool only when truly needed

典型 AWS 方案:

employees
    -> company IdP
        -> IAM Identity Center
            -> AWS accounts / permission sets
employees
    -> company IdP
        -> Cognito User Pool
            -> app receives JWT
                -> backend API verifies JWT
customers / external users
    -> Cognito User Pool
        -> app receives JWT
            -> backend API verifies JWT

11. Account Provisioning#

统一登录只是第一步,真正减少运维工作还要处理账号生命周期。

SSO solves:
    user can log in with central identity
    password and MFA are centralized

SSO does not always solve:
    create app-local user
    assign app-local role
    disable app-local user after resignation
    remove stale groups

常见方式:

Method Meaning When To Use
Manual provisioning 管理员手动创建账号 small number of systems or early phase
JIT provisioning 用户第一次 SSO 登录时自动创建账号 app supports it and default role is safe
SCIM IdP 主动同步用户和组到应用 important SaaS / internal platform
Custom sync 定时从 HR/IdP API 同步 app does not support SCIM

推荐:

critical systems:
    use SCIM or explicit automated provisioning

low-risk internal tools:
    JIT provisioning can be acceptable

high-privilege access:
    do not give admin role by JIT default

leavers:
    central IdP disable must quickly remove access

12. Scenario Choices#

company has many SaaS systems#

choose:
    company IdP + SAML SSO + SCIM where supported

why:
    SaaS vendors commonly support SAML
    SCIM reduces manual account creation/removal

Examples:

Okta / Entra ID / Google Workspace
    -> SAML
        -> Jira / GitLab / Grafana / Slack

Okta / Entra ID
    -> SCIM
        -> create users and sync groups

new internal web app#

choose:
    OIDC Authorization Code + PKCE

why:
    modern app integration
    JWT is easy for backend verification
    works well with APIs

Architecture:

browser
    -> company IdP or Cognito
        -> OIDC code flow
            -> backend verifies JWT
                -> app checks local roles

existing app has no login support#

choose:
    ALB auth / reverse proxy auth / SSO gateway

why:
    avoid rewriting app immediately
    protect route before traffic reaches app

But:

limitation:
    app may only know request headers
    fine-grained authorization still needs app changes

AWS account console access#

choose:
    AWS IAM Identity Center

why:
    designed for workforce access to AWS accounts
    supports permission sets
    integrates with external identity source

Avoid:

creating IAM users for every employee:
    hard to rotate
    hard to disable consistently
    weak governance

customer-facing product login#

choose:
    Cognito User Pool or another CIAM provider

why:
    app-user login is different from employee workforce login
    supports sign-up, password reset, MFA, social login, app clients

Keep separate:

employees:
    workforce IdP

customers:
    customer identity store

service-to-service API#

choose:
    OAuth2 client credentials or cloud-native workload identity

why:
    no human user exists
    machine identity should not use a human password

Examples:

internal worker -> token endpoint -> access token -> API
EKS workload -> IRSA / Pod Identity -> AWS API
EC2/ECS/Lambda -> IAM role -> AWS API

13. Implementation Plan#

Start small and make identity source authoritative.

phase 1: inventory
    list all systems
    record whether each supports SAML, OIDC, SCIM, JIT
    record current admin owners
    record current local admin accounts

phase 2: choose identity source
    Entra ID / Okta / Google Workspace / ADFS / IAM Identity Center internal store
    define MFA policy
    define groups and naming convention

phase 3: connect high-value systems
    AWS IAM Identity Center
    Git / CI/CD
    monitoring
    ticketing
    production admin tools

phase 4: provisioning
    enable SCIM where possible
    define default JIT role carefully
    automate leaver removal

phase 5: app modernization
    new apps use OIDC
    old apps use SAML or auth proxy first
    migrate local passwords out gradually

Inventory template:

System Owner Users Supports SAML Supports OIDC Supports SCIM Current Risk Target
AWS accounts Platform 30 yes n/a via Identity Center IAM users IAM Identity Center
GitLab DevOps 60 yes yes yes local passwords SAML + SCIM
Grafana SRE 20 yes yes depends shared admin OIDC
Internal admin App Team 15 no no no local users ALB auth then OIDC

14. Design Checklist#

identity source:
    one authoritative employee source is selected
    HR joiner/mover/leaver process is connected or documented
    break-glass account policy exists

authentication:
    MFA required for employees
    phishing-resistant MFA considered for privileged users
    local passwords disabled where SSO is enabled

protocol:
    SAML for SaaS / legacy enterprise apps
    OIDC for new custom web/mobile/API apps
    OAuth2 client credentials for machine-to-machine

provisioning:
    SCIM enabled for important systems
    JIT default role is least privilege
    leaver deprovisioning is tested

authorization:
    groups map to application roles intentionally
    admin roles require separate approval
    app still enforces resource-level permissions

operations:
    IdP admin changes are audited
    failed login spikes are monitored
    SAML certificate rotation is tracked
    token verification failures are logged

15. Common Mistakes#

mistake:
    think SSO means no local account exists
result:
    many apps still need a local user record for roles, preferences, ownership, audit

mistake:
    enable SAML but leave local passwords active for everyone
result:
    users can bypass central MFA and leaver process

mistake:
    map every IdP group into every app
result:
    tokens/assertions become large and authorization is hard to reason about

mistake:
    use email as permanent user id
result:
    email rename or domain migration can break identity mapping

mistake:
    use Cognito Identity Pool for normal API login
result:
    browser gets AWS credentials unnecessarily

mistake:
    only implement SSO without SCIM or leaver automation
result:
    login is unified, but old app accounts and permissions still accumulate