Entra ID 的 SSO federation
💫

Entra ID 的 SSO federation

 
notion image
操作步骤详解
这个过程分为三个主要阶段:

阶段一:在 Keycloak 中配置 (作为 IdP)

需要创建一个“客户端”(Client),这个“客户端”就是指 Microsoft Entra ID。
  1. 登录 Keycloak 管理控制台并选择 的 Realm (领域)。
  1. 转到 Clients (客户端) > Create client (创建客户端)。
  1. Client ID (客户端 ID): * 这是 Entra ID 的 SAML "Entity ID"。这个值是固定不变的,必须输入:
      • urn:federation:MicrosoftOnline
  1. Client Protocol (客户端协议): 选择 saml
  1. 点击 Save (保存)。
  1. 配置客户端 (SAML 设置):
      • Name (名称): 任意填写,例如 "Microsoft Entra ID / M365"。
      • Name ID Format (NameID 格式):
        • Entra ID 期望的格式是 persistent (持久化的),Entra ID 需要这个和 ImmutableId 字段进行“锚定”匹配
      notion image
      • Sign Documents (签署文档): 确保为 On (开启)。
  1. 配置 Mappers (映射器 - 关键步骤):
很难找这个位置,点击client-urn:federation:MicrosoftOnline-dedicated-configure a new mapper
notion image
notion image
  • Entra ID 需要两个特定的 SAML 属性 (Claims) 才能识别用户。需要转到 Mappers 选项卡。
  • Mapper 1: UPN (或 Email)
    • Name: IDPEmail,是这个 Mapper 在 Keycloak 内部的名字(自己看的)
    • Mapper Type: User Property (用户属性)
    • Property: email (或 username,取决于 Keycloak 中哪个字段对应 Entra ID 的 UPN),是 Keycloak 从用户数据中“抓取”哪个字段(抓取 email 字段)
    • SAML Attribute Name: IDPEmail (这是 Entra ID 期望的属性名),是当 Keycloak 把这个值(email 的值)放入 SAML 票据时,这个票据里的属性“标签”叫什么名字。
    • notion image
      notion image
  • Mapper 2: ImmutableID (不可变 ID)
    • 这是最关键的部分。Entra ID 需要一个在两个系统中都唯一且永不改变的 ID 来“锚定”用户。
    • 这个 ID 将通过 SAML 的 NameID 字段发送。
    • 在第 6 步中设置了 Name ID Formatpersistent。默认情况下,Keycloak 会使用其内部的用户 GUID (如 f81d4fae-...) 作为 persistent NameID 的值。这是推荐的做法。无需为此创建 Mapper,只需确保 Mappers 选项卡中没有其他配置覆盖了 NameID 即可。
  1. 获取 Keycloak 的元数据:
      • 转到 Realm Settings (领域设置) > General (常规) 选项卡。
      • 找到 Endpoints (端点) 链接并点击。
      • 找到并复制 SAML 2.0 Identity Provider Metadata 的 URL。它看起来像:
        • .../auth/realms/<YourRealm>/protocol/saml/descriptor
      • 需要从这个 XML 元数据中提取三个信息,以便在 PowerShell 中使用:
          1. IssuerUri: entityID 字段的值 (例如 .../auth/realms/\<YourRealm\>)
          1. PassiveLogOnUri: SingleSignOnServiceBindingurn:oasis:names:tc:SAML:2.0:bindings:HTTP-POSTLocation 值。
          1. SigningCertificate: X509Certificate 标签内的那一长串证书字符串(删除所有换行符)。
          notion image
          notion image

阶段二:在 Entra ID 中配置 (使用 PowerShell)

这是将 Entra ID 域从“托管”(Managed) 转换为“联邦”(Federated) 的地方。
  1. 安装 Microsoft Graph 模块 (替代 MSOnline)
      • 打开一个管理员 PowerShell 窗口。
      Install-Module Microsoft.Graph -Force
  1. 连接到 Entra ID (替代 Connect-MsolService)
    1. Connect-MgGraph -Scopes "Domain.ReadWrite.All"
      • 使用全局管理员帐户登录。
  1. 执行联邦转换 (替代 Set-MsolDomainFederationSettings)
      • 将在阶段一(第8步)中获取的值填入以下变量:
      # 1. 定义变量 $domainName = "xiaoyia.com" $logonUrl = "https://sso.stat200.net/realms/master/protocol/saml" $issuerUri = "https://sso.stat200.net/realms/master" $logoffUrl = "https://sso.stat200.net/realms/master/protocol/saml" $cert = "MIICmzCCAYMCBgGafb6KyDANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZtYXN0ZXIwHhcNMjUxMTEzMTUwMjEwWhcNMzUxMTEzMTUwMzUwWjARMQ8wDQYDVQQDDAZtYXN0ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCxSubVXpwQ/NLGv86L0l/7eHTktRvO6KK5UBnFmWsHiugX37vE54cq9TX7EG1TOuitX6Lqoz14hwK6gPNwJTQgrPRuRgZIDmOBM0+m0O70hJBRanUXpOjBs8pJX5P4x82o3bpapR+1Y4K9mG6AWg0cijzFsHC6q/AszqS0q4TuYqHefHFSM0XoTXQ+UoKlkCPAeVPagmSbx756iDWV+HBf4O3Oz0jgV1+TSME46+JcUuKHmlTkHVYp706qo2G/tt9PnWQaWi/MB690T5AcJqmyrAxNbhM7g7Ah8w35FYBhVmLsVITUU2Qxcdz4AEd6uowEsjcimksOCcOTbuZ3KVONAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAF65KC3p1wX84oHi5y18RoQ1xPipXVWb5ocZtKMkD1uRdJh5Ll3IlHP+/ep5/qJqz2zk4neoHh0870Mck4d5AQ4pqsnm+HzdHz/Y29wrfsGKmNgWgGmfXpRY6KLymqAYy5zEF2ZfXW3fuQkgVOOMYISRMvRSpjgYkRdjmVJKUQRsQm2ZB3ODQGzbTO8ROTM/RkM+vAgZ+CXwjN7P6tnFVdolSxj1Ml5e+0XtzJvPHmyHUrWBaKvA1JHnd0Cs3m4KkojgQbiC8sU5Cjww8ED5JZkx+vs/hKomHMncfEkWtwCzS2ya3qkMN6qON6eT+BZhY0vxDakvROWSXpLjDZUgjk4=" # 2. 执行 New-MgDomainFederationConfiguration -DomainId $domainName -IssuerUri $issuerUri -PassiveSignInUri $logonUrl -SignOutUri $logoffUrl -SigningCertificate $cert -PreferredAuthenticationProtocol "saml" -FederatedIdpMfaBehavior "acceptIfMfaDoneByFederatedIdp"
  1. 验证:
      • 运行 Get-MgDomainFederationConfiguration -DomainId "xiaoyia.com”
      • 应该能看到刚才输入的所有 Keycloak URL 和证书信息,证明配置已生效。
      notion image

  1. Entra ID创建用户时报错
notion image
💡
AAD认为既然这个域名归 Keycloak 管,那这个用户肯定是从外部(比如 Keycloak 或本地 AD)同步过来的。为了防止认错人,你必须给我一个唯一的身份证号( SourceAnchor 也就是 ImmutableId) 所以必须通过命令行来创建这个用户,把OnPremisesImmutableId填进去
但是OnPremisesImmutableId从哪来
需要在keycloak中添加属性,且勾选required field,这样在创建用户的时候必须要有uuid的值
notion image
notion image
notion image
然后在client中需要将uuid匹配到nameID
notion image
notion image
# 1. 准备用户信息 $userParams = @{ DisplayName = "SSO User" UserPrincipalName = "sso@stat200.net" # 目标用户名 MailNickname = "sso" UsageLocation = "CN" # 国家代码 AccountEnabled = $true PasswordProfile = @{ Password = "Password123!" # 初始密码 (其实用不到,因为要去Keycloak验证) ForceChangePasswordNextSignIn = $false } # 关键的一行 OnPremisesImmutableId = "uuid-be544fc0-cd6f-410b-9122-a45143419ec9" # 这里的 ID 必须和 Keycloak 发过来的 NameID 一致 } # 2. 连接 Graph (如果没断开可跳过) Connect-MgGraph -Scopes "User.ReadWrite.All" # 3. 更新用户 Update-MgUser @userParams
💡
小技巧:
  • Federated 域名用户创建限制
    • 当域名在 Entra ID 中配置为 Federated,创建用户时必须提供 SourceAnchor,否则无法与本地 AD 的 OnPremisesImmutableId 匹配。
  • 直接 update 会失败的原因
    • 如果在命令行直接更新 Federated 域用户,但 Entra ID 中没有 SourceAnchor,就无法完成匹配,因此会失败。
  • 解决方案
    • 先创建一个非 Federated 域名的账号(例如 @stat200.net),再通过命令行同步用户信息并传入 OnPremisesImmutableId,最后修改用户属性,将 UPN 改为 Federated 域名(例如 @xiaoyia.com)。
notion image
notion image

测试

  1. 打开一个浏览器隐私模式
  1. 访问 https://portal.azure.com
  1. 输入 的联邦域邮箱,sso@xiaoyia.com
  1. 不要输入密码。当 点击 "下一步" 或按 Tab 键时,Entra ID 会检测到xiaoyia.com是一个联邦域。
  1. 将被自动重定向到 Keycloak 的登录页面 ( 在 \$logonUrl 中设置的地址)。
  1. 使用 在 Keycloak 中为此用户设置的密码登录。
  1. Keycloak 验证成功,将 重定向回 Entra ID (login.srf)。
  1. Entra ID 验证 SAML 响应,通过 ImmutableId 找到匹配的用户,登录成功。
notion image
报错
notion image
notion image
notion image
💡
关掉 client signature required!!
notion image
跳转不再报错
notion image
跳回AAD
notion image
notion image
成功!!
notion image