本文介绍如何将安全断言标记语言 (SAML) 应用程序(服务提供程序)连接到 Azure Active Directory B2C (Azure AD B2C) 以进行身份验证。
开始之前,请使用此页顶部的“选择策略类型”选择器来选择要设置的策略类型。 Azure Active Directory B2C 提供了两种定义用户如何与应用程序交互的方法:通过预定义的用户流,或者通过可完全配置的自定义策略。 对于每种方法,本文中所需的步骤都不同。
此功能仅适用于自定义策略。 对于设置步骤,请在前面的选择器中选择“自定义策略”。
使用 Azure AD B2C 作为客户标识并访问管理解决方案的组织可能需要与使用 SAML 协议进行身份验证的应用程序集成。 下图显示了如何将 Azure AD B2C 用作标识提供者 (IdP),在基于 SAML 的应用程序中实现单一登录 (SSO)。
- 应用程序创建一个要发送到 Azure AD B2C SAML 登录终结点的 SAML AuthN 请求。
- 用户可以使用 Azure AD B2C 本地帐户或任何其他联合标识提供者(如果已配置)进行身份验证。
- 如果用户使用联合标识提供者登录,令牌响应会发送到 Azure AD B2C。
- Azure AD B2C 生成 SAML 断言并将其发送到应用程序。
对于本文中的应用场景,需具备以下项:
- 自定义策略初学者包中的 SocialAndLocalAccounts 自定义策略。 完成 Azure AD B2C 中的自定义策略中的步骤。
- 基本了解 SAML 协议,并熟悉应用程序的 SAML 实现。
- 一个已配置为 SAML 应用程序的应用程序。 它必须能够发送 SAML AuthN 请求,以及接收、解码和验证来自 Azure AD B2C 的 SAML 响应。 SAML 应用程序也称为信赖方应用程序或服务提供程序。
- SAML 应用程序的公开可用 SAML 元数据终结点或 XML 文档。
- Azure AD B2C 租户。
如果你没有 SAML 应用程序和关联的元数据终结点,可以使用我们提供的用于测试的 SAML 测试应用程序。
若要在应用程序和 Azure AD B2C 之间建立信任关系,这两个服务必须能够创建和验证彼此的签名。 在应用程序和 Azure AD B2C 中配置 X509 证书。
应用程序证书
使用情况 | 必需 | 说明 |
---|---|---|
SAML 请求签名 | 否 | 一个证书,其私钥存储在你的 Web 应用中。 应用程序使用该证书对发送到 Azure AD B2C 的 SAML 请求进行签名。 Web 应用必须通过其 SAML 元数据终结点公开公钥。 Azure AD B2C 使用应用程序元数据中的公钥来验证 SAML 请求签名。 |
SAML 断言加密 | 否 | 一个证书,其私钥存储在你的 Web 应用中。 Web 应用必须通过其 SAML 元数据终结点公开公钥。 Azure AD B2C 可以使用公钥在应用程序中加密断言。 应用程序使用私钥来解密断言。 |
Azure AD B2C 证书
使用情况 | 必需 | 说明 |
---|---|---|
SAML 响应签名 | 是 | 一个证书,其私钥存储在 Azure AD B2C 中。 Azure AD B2C 使用此证书对发送到应用程序的 SAML 响应进行签名。 应用程序读取 Azure AD B2C 中的元数据公钥以验证 SAML 响应的签名。 |
SAML 断言签名 | 是 | 一个证书,其私钥存储在 Azure AD B2C 中。 Azure AD B2C 使用此证书对 SAML 响应的 <saml:Assertion> 部分进行签名。 |
在生产环境中,我们建议使用公共证书颁发机构颁发的证书。 不过,你也可以使用自签名证书完成此过程。
若要在应用程序和 Azure AD B2C 之间建立信任关系,请创建 SAML 响应的签名证书。 Azure AD B2C 使用此证书对发送到应用程序的 SAML 响应进行签名。 应用程序读取 Azure AD B2C 的元数据公钥以验证 SAML 响应的签名。
提示
可以使用此策略密钥实现其他目的,例如对 SAML 断言进行签名。
如果你还没有证书,则可以使用自签名证书。 自签名证书是未由证书颁发机构 (CA) 签署的安全证书,不提供由 CA 签名的证书的安全保障。
在 Windows 上,可在 PowerShell 中使用 New-SelfSignedCertificate cmdlet 来生成证书。
运行以下 PowerShell 命令来生成自签名证书。 根据应用程序和 Azure AD B2C 租户名称修改
-Subject
参数,如contosowebapp.contoso.partner.onmschina.cn
。 还可调整-NotAfter
日期,为证书指定不同的过期日期。New-SelfSignedCertificate ` -KeyExportPolicy Exportable ` -Subject "CN=yourappname.yourtenant.partner.onmschina.cn" ` -KeyAlgorithm RSA ` -KeyLength 2048 ` -KeyUsage DigitalSignature ` -NotAfter (Get-Date).AddMonths(12) ` -CertStoreLocation "Cert:\CurrentUser\My"
在 Windows 计算机上,搜索并选择“管理用户证书”
在“证书 - 当前用户”下,选择“个人”“证书”“yourappname.yourtenant.partner.onmschina.cn”。
选择该证书,然后依次选择“操作”>“所有任务”>“导出”。
选择“下一步”>“是,导出私钥”>“下一步” 。
接受“导出文件格式”的默认值,然后选择“下一步” 。
启用“密码”选项,输入证书的密码,然后选择“下一步” 。
若要指定保存证书的位置,请选择“浏览”并导航到所选的目录。
在“另存为”窗口中,输入文件名,然后选择“保存” 。
选择“下一步”>“完成”。
要让 Azure AD B2C 接受 .pfx 文件密码,必须在 Windows 证书存储导出实用工具中使用 TripleDES-SHA1 选项,而不是 AES256-SHA256 对此密码进行加密。
需要将你的证书存储在 Azure AD B2C 租户中。
- 登录 Azure 门户。
- 如果有权访问多个租户,请选择顶部菜单中的“设置”图标,切换到“目录 + 订阅”菜单中的 Azure AD B2C 租户。
- 选择 Azure 门户左上角的“所有服务”,然后搜索并选择“Azure AD B2C”。
- 在“概述”页上,选择“Identity Experience Framework”。
- 选择“策略密钥”,然后选择“添加” 。
- 对于“选项”,请选择“上传”。
- 对于“名称”,输入策略密钥的名称。 例如,输入“SamlIdpCert”。 前缀“B2C_1A_”会自动添加到密钥名称中。
- 浏览并选择带有私钥的证书 .pfx 文件。
- 选择“创建”。
若要连接到 SAML 应用程序,Azure AD B2C 必须能够创建 SAML 响应。
在自定义策略初学者包中打开 SocialAndLocalAccounts\TrustFrameworkExtensions.xml。
找到 <ClaimsProviders>
一节,并添加以下 XML 代码片段来实现 SAML 响应生成器:
<ClaimsProvider>
<DisplayName>Token Issuer</DisplayName>
<TechnicalProfiles>
<!-- SAML Token Issuer technical profile -->
<TechnicalProfile Id="Saml2AssertionIssuer">
<DisplayName>Token Issuer</DisplayName>
<Protocol Name="SAML2"/>
<OutputTokenFormat>SAML2</OutputTokenFormat>
<Metadata>
<Item Key="IssuerUri">https://issuerUriMyAppExpects</Item>
</Metadata>
<CryptographicKeys>
<Key Id="SamlAssertionSigning" StorageReferenceId="B2C_1A_SamlIdpCert"/>
<Key Id="SamlMessageSigning" StorageReferenceId="B2C_1A_SamlIdpCert"/>
</CryptographicKeys>
<InputClaims/>
<OutputClaims/>
<UseTechnicalProfileForSessionManagement ReferenceId="SM-Saml-issuer"/>
</TechnicalProfile>
<!-- Session management technical profile for SAML-based tokens -->
<TechnicalProfile Id="SM-Saml-issuer">
<DisplayName>Session Management Provider</DisplayName>
<Protocol Name="Proprietary" Handler="Web.TPEngine.SSO.SamlSSOSessionProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
</TechnicalProfile>
</TechnicalProfiles>
</ClaimsProvider>
可以在 SAML 令牌颁发者技术配置文件中更改 IssuerUri
元数据项的值。 此项更改将反映在 Azure AD B2C 做出的 SAML 响应中返回的 issuerUri
特性内。 配置应用程序以在 SAML 响应验证期间接受相同的 IssuerUri
值。
<ClaimsProvider>
<DisplayName>Token Issuer</DisplayName>
<TechnicalProfiles>
<!-- SAML Token Issuer technical profile -->
<TechnicalProfile Id="Saml2AssertionIssuer">
<DisplayName>Token Issuer</DisplayName>
<Protocol Name="SAML2"/>
<OutputTokenFormat>SAML2</OutputTokenFormat>
<Metadata>
<Item Key="IssuerUri">https://issuerUriMyAppExpects</Item>
</Metadata>
...
</TechnicalProfile>
你的策略现在可以创建 SAML 响应,必须将策略配置为向应用程序发出 SAML 响应,而不是默认的 JWT 响应。
在初学者包的工作目录中创建 SignUpOrSignin.xml 文件的副本,并使用新名称保存该副本。 本文以“SignUpOrSigninSAML.xml”为例。 此文件是你对信赖方的策略文件。 它默认配置为发出 JWT 响应。
在首选编辑器中打开“SignUpOrSigninSAML.xml”文件。
更改以下项的值:
PolicyId
至B2C_1A_signup_signin_saml
PublicPolicyUri
重命名为http://<tenant-name>.partner.onmschina.cn/B2C_1A_signup_signin_saml
。 将<tenant-name>
占位符替换为 Azure AD B2C 租户域名的子域。 例如,如果租户主域为contoso.partner.onmschina.cn
,请使用contoso
。 如果没有租户名称,请了解如何读取租户详细信息。
<TrustFrameworkPolicy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.microsoft.com/online/cpim/schemas/2013/06" PolicySchemaVersion="0.3.0.0" TenantId="<tenant-name>.partner.onmschina.cn" PolicyId="B2C_1A_signup_signin_saml" PublicPolicyUri="http://<tenant-name>.partner.onmschina.cn/B2C_1A_signup_signin_saml">
用户旅程结束时,Azure AD B2C 将包含
SendClaims
步骤。 此步骤引用令牌颁发者技术配置文件。 若要发出 SAML 响应而不是默认的 JWT 响应,请修改SendClaims
步骤,以引用新的 SAML 令牌颁发者技术配置文件Saml2AssertionIssuer
。
紧靠在 <RelyingParty>
元素的前面添加以下 XML 代码片段。 此 XML 将覆盖 SignUpOrSignIn 用户旅程中的业务流程步骤 7。
如果已从初学者包中的不同文件夹启动,或者通过添加或删除业务流程步骤自定义了用户旅程,请确保 order
元素中的编号对应于用户旅程中为令牌颁发者步骤指定的编号。 例如,在其他初学者包文件夹中,LocalAccounts
、SocialAccounts
和 SocialAndLocalAccountsWithMfa
的对应步骤编号分别为 4、6、9。
<UserJourneys>
<UserJourney Id="SignUpOrSignIn">
<OrchestrationSteps>
<OrchestrationStep Order="7" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="Saml2AssertionIssuer"/>
</OrchestrationSteps>
</UserJourney>
</UserJourneys>
信赖方元素确定应用程序使用的协议。 默认为 OpenId
。 必须将 Protocol
元素更改为 SAML
。 输出声明将创建到 SAML 断言的声明映射。
将 <RelyingParty>
元素中的整个 <TechnicalProfile>
元素替换为以下技术配置文件 XML。
<TechnicalProfile Id="PolicyProfile">
<DisplayName>PolicyProfile</DisplayName>
<Protocol Name="SAML2"/>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="displayName" />
<OutputClaim ClaimTypeReferenceId="givenName" />
<OutputClaim ClaimTypeReferenceId="surname" />
<OutputClaim ClaimTypeReferenceId="email" DefaultValue="" />
<OutputClaim ClaimTypeReferenceId="identityProvider" DefaultValue="" />
<OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="objectId"/>
</OutputClaims>
<SubjectNamingInfo ClaimType="objectId" ExcludeAsClaim="true"/>
</TechnicalProfile>
信赖方的最终策略文件应如以下 XML 代码所示:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<TrustFrameworkPolicy
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://schemas.microsoft.com/online/cpim/schemas/2013/06"
PolicySchemaVersion="0.3.0.0"
TenantId="contoso.partner.onmschina.cn"
PolicyId="B2C_1A_signup_signin_saml"
PublicPolicyUri="http://contoso.partner.onmschina.cn/B2C_1A_signup_signin_saml">
<BasePolicy>
<TenantId>contoso.partner.onmschina.cn</TenantId>
<PolicyId>B2C_1A_TrustFrameworkExtensions</PolicyId>
</BasePolicy>
<UserJourneys>
<UserJourney Id="SignUpOrSignIn">
<OrchestrationSteps>
<OrchestrationStep Order="7" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="Saml2AssertionIssuer"/>
</OrchestrationSteps>
</UserJourney>
</UserJourneys>
<RelyingParty>
<DefaultUserJourney ReferenceId="SignUpOrSignIn" />
<TechnicalProfile Id="PolicyProfile">
<DisplayName>PolicyProfile</DisplayName>
<Protocol Name="SAML2"/>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="displayName" />
<OutputClaim ClaimTypeReferenceId="givenName" />
<OutputClaim ClaimTypeReferenceId="surname" />
<OutputClaim ClaimTypeReferenceId="email" DefaultValue="" />
<OutputClaim ClaimTypeReferenceId="identityProvider" DefaultValue="" />
<OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="objectId"/>
</OutputClaims>
<SubjectNamingInfo ClaimType="objectId" ExcludeAsClaim="true"/>
</TechnicalProfile>
</RelyingParty>
</TrustFrameworkPolicy>
备注
可以遵循上述相同过程来实现其他类型的用户流(例如登录、密码重置或配置文件编辑流)。
保存更改,并将新的 TrustFrameworkExtensions.xml 和 SignUpOrSigninSAML.xml 策略文件上传到 Azure 门户 。
上传策略文件后,Azure AD B2C 将使用配置信息来生成应用程序使用的标识提供者 SAML 元数据文档。 SAML 元数据文档包含服务的位置,例如登录方法、注销方法和证书。
以下 URL 提供了 Azure AD B2C 策略元数据:
https://<tenant-name>.b2clogin.cn/<tenant-name>.partner.onmschina.cn/<policy-name>/samlp/metadata
将 <tenant-name>
替换为 Azure AD B2C 租户的名称。 将 <policy-name>
替换为策略的名称 (ID)。 下面是一个示例:
https://contoso.b2clogin.cn/contoso.partner.onmschina.cn/B2C_1A_signup_signin_saml/samlp/metadata
要使 Azure AD B2C 信任你的应用程序,你需要创建一个 Azure AD B2C 应用程序注册。 注册包含配置信息,如应用程序的元数据终结点。
- 登录 Azure 门户。
- 如果有权访问多个租户,请选择顶部菜单中的“设置”图标,切换到“目录 + 订阅”菜单中的 Azure AD B2C 租户。
- 在左侧菜单中,选择“Azure AD B2C”。 或者,选择“所有服务”,然后搜索并选择“Azure AD B2C”。
- 选择“应用注册”,然后选择“新建注册” 。
- 输入应用程序的“名称”。 例如,输入“SAMLApp1”。
- 在“支持的帐户类型”下,选择“仅此组织目录中的帐户” 。
- 在“重定向 URI”下,选择“Web”,然后输入
https://localhost
。 稍后你将在应用程序注册的清单中修改此值。 - 选择“注册” 。
对于 SAML 应用,需要在应用程序注册的清单中配置几个属性。
- 在 Azure 门户中,转到在上一节中创建的应用程序注册。
- 在“管理”下,选择“清单”以打开清单编辑器。 然后修改以下各节中介绍的属性。
当 SAML 应用程序向 Azure AD B2C 发出请求时,SAML AuthN 请求将包含一个 Issuer
特性。 此特性的值通常与应用程序的元数据 entityID
值相同。 Azure AD B2C 使用此值在目录中查找应用程序注册并读取配置。 要使此查找操作成功,必须使用与 Issuer
特性匹配的值来填充应用程序注册中的 identifierUri
。
在注册清单中,找到 identifierURIs
参数并添加适当的值。 此值将与在应用程序的 SAML AuthN 请求中为 EntityId
配置的值,以及应用程序元数据中的 entityID
值相同。 还将需要找到 accessTokenAcceptedVersion
参数,并将值设置为 2
。
重要
如果不将 accessTokenAcceptedVersion
更新为 2
,你将收到一条错误消息,要求提供一个经过验证的域。
以下示例展示了 SAML 元数据中的 entityID
值:
<EntityDescriptor ID="id123456789" entityID="https://samltestapp2.chinacloudsites.cn" validUntil="2099-12-31T23:59:59Z" xmlns="urn:oasis:names:tc:SAML:2.0:metadata">
identifierUris
属性仅接受域 tenant-name.partner.onmschina.cn
上的 URL。
"identifierUris":"https://tenant-name.partner.onmschina.cn/app-name",
在应用程序注册由其 identifierUri
值加载后,Azure AD B2C 将使用应用程序的元数据来验证 SAML AuthN 请求,并确定如何做出响应。
我们建议让应用程序公开一个可公开访问的元数据终结点。
如果在 SAML 元数据 URL 和应用程序注册的清单中都指定了一些属性,则这些属性将合并。 会优先处理元数据 URL 中指定的属性,其优先级更高。
以 SAML 测试应用程序为例,可以在应用程序清单中为 samlMetadataUrl
使用以下值:
"samlMetadataUrl":"https://samltestapp2.chinacloudsites.cn/Metadata",
可以配置 Azure AD B2C 要向其发送 SAML 响应的回复 URL。 可以在应用程序清单中配置回复 URL。 当应用程序未公开一个可公开访问的元数据终结点时,此配置非常有用。
SAML 应用程序的回复 URL 是应用程序预期在其上接收 SAML 响应的终结点。 应用程序通常在元数据文档中提供此 URL 作为 AssertionConsumerService
元素的 Location
特性,如以下示例中所示:
<SPSSODescriptor AuthnRequestsSigned="false" WantAssertionsSigned="false" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
...
<AssertionConsumerService index="0" isDefault="true" Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://samltestapp2.chinacloudsites.cn/SP/AssertionConsumer" />
</SPSSODescriptor>
如果缺少应用程序的元数据 AssertionConsumerService
元素,或者你想要重写它,请配置应用程序注册清单 replyUrlsWithType
属性。 Azure AD B2C 使用 replyUrlsWithType
在用户使用 HTTP-POST
绑定类型登录后重定向用户。
以 SAML 测试应用程序为例,可将 replyUrlsWithType
的 url
属性设置为以下 JSON 代码片段中显示的值:
"replyUrlsWithType":[
{
"url":"https://samltestapp2.chinacloudsites.cn/SP/AssertionConsumer",
"type":"Web"
}
],
注销 URL 定义了注销请求后将用户重定向到的位置。 应用程序通常在元数据文档中提供此 URL 作为 SingleLogoutService
元素的 Location
特性,如下面的示例中所示:
<SPSSODescriptor AuthnRequestsSigned="false" WantAssertionsSigned="false" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://samltestapp2.chinacloudsites.cn/logout" ResponseLocation="https://samltestapp2.chinacloudsites.cn/logout" />
</SPSSODescriptor>
如果缺少应用程序的元数据 SingleLogoutService
元素,请配置应用程序注册清单 logoutUrl
属性。 Azure AD B2C 使用 logoutURL
在用户使用 HTTP-Redirect
绑定类型注销后重定向用户。
以 SAML 测试应用程序为例,你会将 logoutUrl
属性设置为 https://samltestapp2.chinacloudsites.cn/logout
:
"logoutUrl": "https://samltestapp2.chinacloudsites.cn/logout",
备注
如果你选择在应用程序清单中配置回复 URL 和注销 URL,而不通过 samlMetadataUrl
属性填充应用程序的元数据终结点,Azure AD B2C 将不会验证 SAML 请求签名。 也不会加密 SAML 响应。
最后一步是在 SAML 应用程序中将 Azure AD B2C 启用为 SAML IdP。 应用程序各不相同,因此步骤也不相同。 有关详细信息,请参阅应用的文档。
可以在应用程序中将元数据配置为静态元数据或动态元数据 。 在静态模式下,复制 Azure AD B2C 策略元数据中的所有或一部分元数据。 在动态模式下,提供元数据的 URL 并允许应用程序动态读取元数据。
通常需要以下部分或全部内容:
元数据:使用格式 。
颁发者:SAML 请求的
issuer
值必须与在应用注册清单的identifierUris
元素中配置的 URI 之一匹配。 如果 SAML 请求的issuer
名称不存在于identifierUris
元素中,则issuer
。 例如:https://contoso.partner.onmschina.cn/app-name
。登录 URL、SAML 终结点、SAML URL:检查 Azure AD B2C SAML 策略元数据文件中 XML 元素的值。
证书:此证书为 B2C_1A_SamlIdpCert,但不包含私钥。 若要获取证书的公钥:
- 转到之前指定的元数据 URL。
- 复制
<X509Certificate>
元素中的值。 - 将其粘贴到文本文件中。
- 将该文本文件另存为 .cer 文件。
可以使用我们的 SAML 测试应用程序来测试你的配置:
- 更新租户名称。
- 更新策略名称。 例如,使用 B2C_1A_signup_signin_saml。
- 指定颁发者 URI。 使用在应用程序注册清单的
identifierUris
元素中找到的 URI 之一。 例如,使用https://contoso.partner.onmschina.cn/app-name
。
选择“登录”,应会显示用户登录屏幕。 登录后,SAML 响应将发回示例应用程序。
可通过你自己的元数据终结点支持以下 SAML 应用程序方案:
- 指定应用程序或服务主体对象中的多个注销 URL 或注销 URL 的 POST 绑定。
- 指定签名密钥,以验证应用程序或服务主体对象中的信赖方请求。
- 在应用程序或服务主体对象中指定令牌加密密钥。
- 指定 IdP 发起的登录,其中的标识提供者是 Azure AD B2C。
- 从 Azure AD B2C GitHub 社区存储库获取 SAML 测试 Web 应用。
- 请参阅用于在 Azure AD B2C 中注册 SAML 应用程序的选项。
- 了解如何通过开发人员最佳做法构建复原能力。