Links#
- Amazon Cognito SAML identity providers
- Amazon Cognito identity federation
- What is AWS IAM Identity Center
- IAM Identity Center identity source
- OpenID Connect overview
- SAML standard
- Keycloak Server Administration Guide
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 centrallySSO 本身不是协议。实现 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 protocol5. 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 usersSP 是服务提供方。它不自己维护员工密码,而是信任 IdP 的登录结果。
examples:
GitLab
Jira
Confluence
Grafana
AWS IAM Identity Center
internal admin system
payroll systemSAML 里通常叫:
IdP:
identity provider
SP:
service providerOIDC 里通常叫:
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 tokenKeycloak 在这里通常是协议层和策略层,不是 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 SSO6. 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 sessionSAML 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 that7. 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/provisioning8. 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 OIDC10. 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 setsemployees
-> company IdP
-> Cognito User Pool
-> app receives JWT
-> backend API verifies JWTcustomers / external users
-> Cognito User Pool
-> app receives JWT
-> backend API verifies JWT11. 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 access12. 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/removalExamples:
Okta / Entra ID / Google Workspace
-> SAML
-> Jira / GitLab / Grafana / Slack
Okta / Entra ID
-> SCIM
-> create users and sync groupsnew internal web app#
choose:
OIDC Authorization Code + PKCE
why:
modern app integration
JWT is easy for backend verification
works well with APIsArchitecture:
browser
-> company IdP or Cognito
-> OIDC code flow
-> backend verifies JWT
-> app checks local rolesexisting app has no login support#
choose:
ALB auth / reverse proxy auth / SSO gateway
why:
avoid rewriting app immediately
protect route before traffic reaches appBut:
limitation:
app may only know request headers
fine-grained authorization still needs app changesAWS account console access#
choose:
AWS IAM Identity Center
why:
designed for workforce access to AWS accounts
supports permission sets
integrates with external identity sourceAvoid:
creating IAM users for every employee:
hard to rotate
hard to disable consistently
weak governancecustomer-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 clientsKeep separate:
employees:
workforce IdP
customers:
customer identity storeservice-to-service API#
choose:
OAuth2 client credentials or cloud-native workload identity
why:
no human user exists
machine identity should not use a human passwordExamples:
internal worker -> token endpoint -> access token -> API
EKS workload -> IRSA / Pod Identity -> AWS API
EC2/ECS/Lambda -> IAM role -> AWS API13. 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 graduallyInventory 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 logged15. 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