你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
使用 Azure Active Directory B2C 设置通过 LinkedIn 帐户注册与登录
开始之前,可以使用“选择策略类型”选择器来选择要设置的策略类型。 Azure Active Directory B2C 提供了两种定义用户如何与应用程序交互的方法:通过预定义的用户流,或者通过可完全配置的自定义策略。 对于每种方法,本文中所需的步骤都不同。
注意
在 Azure Active Directory B2C 中,自定义策略主要用于解决复杂的情况。 在大多数情况下,建议你使用内置用户流。 如果尚未这样做,请从 Active Directory B2C 中的自定义策略入门了解自定义策略新手包。
必备条件
- 创建用户流,以便用户能够注册并登录应用程序。
- 注册 Web 应用程序。
创建 LinkedIn 应用程序
若要在 Azure Active Directory B2C (Azure AD B2C) 中为使用 LinkedIn 帐户的用户启用登录,你需要在 LinkedIn 开发人员网站中创建应用程序。 有关详细信息,请参阅授权代码流。 如果你没有 LinkedIn 帐户,可在 https://www.linkedin.com/ 上注册一个。
- 使用 LinkedIn 帐户凭据登录到 LinkedIn 开发人员网站。
- 选择“我的应用”,然后单击“创建应用”。
- 输入应用名称、LinkedIn 页、隐私策略 URL 和应用徽标。
- 同意 LinkedIn 的“API 使用条款”并单击“创建应用”。
- 选择“身份验证”选项卡。在“身份验证密钥”下,复制“客户端 ID”和“客户端密码”的值。 将 LinkedIn 配置为租户中的标识提供者时需要这两个值。 “客户端密钥”是一个很重要的安全凭据。
- 选择“应用的授权重定向 URL”旁边的编辑铅笔,然后选择“添加重定向 URL”。 输入
https://your-tenant-name.b2clogin.com/your-tenant-name.onmicrosoft.com/oauth2/authresp
。 如果使用自定义域,请输入https://your-domain-name/your-tenant-name.onmicrosoft.com/oauth2/authresp
。 将your-tenant-name
替换为租户的名称,将your-domain-name
替换为你的自定义域。 输入租户名称时,必须全部使用小写字母,即使租户是使用大写字母在 Azure AD B2C 中定义的,也是如此。 选择“更新”。 - 默认情况下,LinkedIn 应用未获准使用与登录相关的作用域。 若要请求评审,请选择“产品”选项卡,然后选择“使用 LinkedIn 登录”。 评审完成后,所需作用域会添加到你的应用程序。
注意
可以在“OAuth 2.0 作用域”部分的“身份验证”选项卡上查看目前允许应用使用的作用域。
将 LinkedIn 配置为标识提供者
- 以 Azure AD B2C 租户的全局管理员身份登录 Azure 门户。
- 如果有权访问多个租户,请选择顶部菜单中的“设置”图标,从“目录 + 订阅”菜单切换到你的 Azure AD B2C 租户。
- 选择 Azure 门户左上角的“所有服务”,搜索并选择 Azure AD B2C。
- 选择“标识提供者”,然后选择“LinkedIn”。
- 输入“名称”。 例如 LinkedIn。
- 对于“客户端 ID”,请输入前面创建的 LinkedIn 应用程序的客户端 ID。
- 对于“客户端密码”,请输入已记录的客户端密码。
- 选择“保存”。
将 LinkedIn 标识提供者添加到用户流
此时,LinkedIn 标识提供者已设置,但还不能在任何登录页中使用。 将 LinkedIn 标识提供者添加到用户流:
- 在 Azure AD B2C 租户中,选择“用户流” 。
- 单击要添加 LinkedIn 标识提供者的用户流。
- 在“社交标识提供者”下,选择“LinkedIn”。
- 选择“保存”。
- 若要测试策略,请选择“运行用户流”。
- 对于“应用程序”,请选择前面已注册的名为“testapp1”的 Web 应用程序。 “回复 URL”应显示为
https://jwt.ms
。 - 选择“运行用户流”按钮。
- 在注册或登录页面上,选择“LinkedIn”以使用 LinkedIn 帐户登录。
如果登录过程是成功的,则你的浏览器会被重定向到 https://jwt.ms
,其中显示 Azure AD B2C 返回的令牌内容。
创建策略密钥
你需要存储前面在 Azure AD B2C 租户中记录的客户端机密。
- 登录 Azure 门户。
- 如果有权访问多个租户,请选择顶部菜单中的“设置”图标,切换到“目录 + 订阅”菜单中的 Azure AD B2C 租户。
- 选择 Azure 门户左上角的“所有服务”,然后搜索并选择“Azure AD B2C” 。
- 在“概述”页上选择“标识体验框架”。
- 选择“策略密钥”,然后选择“添加”。
- 对于“选项”,请选择
Manual
。 - 输入策略密钥的名称。 例如,
LinkedInSecret
。 前缀“B2C_1A_”会自动添加到密钥名称中。 - 在“机密”中,输入前面记录的客户端密码。
- 在“密钥用法”处选择
Signature
。 - 单击“创建”。
将 LinkedIn 配置为标识提供者
若要允许用户使用 LinkedIn 帐户登录,需将该帐户定义为 Azure AD B2C 可通过终结点与其进行通信的声明提供程序。 该终结点将提供一组声明,Azure AD B2C 使用这些声明来验证特定的用户是否已完成身份验证。
通过在策略的扩展文件中将 LinkedIn 帐户添加到 ClaimsProvider 元素,将该帐户定义为声明提供程序。
在编辑器中,打开 SocialAndLocalAccounts/TrustFrameworkExtensions.xml 文件。 此文件位于自定义策略初学者包中,你已将其作为必备组件之一的一部分下载。
找到 ClaimsProviders 元素。 如果该元素不存在,请在根元素下添加它。
如下所示添加新的 ClaimsProvider:
<ClaimsProvider> <Domain>linkedin.com</Domain> <DisplayName>LinkedIn</DisplayName> <TechnicalProfiles> <TechnicalProfile Id="LinkedIn-OAuth2"> <DisplayName>LinkedIn</DisplayName> <Protocol Name="OAuth2" /> <Metadata> <Item Key="ProviderName">linkedin</Item> <Item Key="authorization_endpoint">https://www.linkedin.com/oauth/v2/authorization</Item> <Item Key="AccessTokenEndpoint">https://www.linkedin.com/oauth/v2/accessToken</Item> <Item Key="ClaimsEndpoint">https://api.linkedin.com/v2/me</Item> <Item Key="scope">r_emailaddress r_liteprofile</Item> <Item Key="HttpBinding">POST</Item> <Item Key="external_user_identity_claim_id">id</Item> <Item Key="BearerTokenTransmissionMethod">AuthorizationHeader</Item> <Item Key="ResolveJsonPathsInJsonTokens">true</Item> <Item Key="UsePolicyInRedirectUri">false</Item> <Item Key="client_id">Your LinkedIn application client ID</Item> </Metadata> <CryptographicKeys> <Key Id="client_secret" StorageReferenceId="B2C_1A_LinkedInSecret" /> </CryptographicKeys> <InputClaims /> <OutputClaims> <OutputClaim ClaimTypeReferenceId="issuerUserId" PartnerClaimType="id" /> <OutputClaim ClaimTypeReferenceId="givenName" PartnerClaimType="firstName.localized" /> <OutputClaim ClaimTypeReferenceId="surname" PartnerClaimType="lastName.localized" /> <OutputClaim ClaimTypeReferenceId="identityProvider" DefaultValue="linkedin.com" AlwaysUseDefaultValue="true" /> <OutputClaim ClaimTypeReferenceId="authenticationSource" DefaultValue="socialIdpAuthentication" AlwaysUseDefaultValue="true" /> </OutputClaims> <OutputClaimsTransformations> <OutputClaimsTransformation ReferenceId="ExtractGivenNameFromLinkedInResponse" /> <OutputClaimsTransformation ReferenceId="ExtractSurNameFromLinkedInResponse" /> <OutputClaimsTransformation ReferenceId="CreateRandomUPNUserName" /> <OutputClaimsTransformation ReferenceId="CreateUserPrincipalName" /> <OutputClaimsTransformation ReferenceId="CreateAlternativeSecurityId" /> <OutputClaimsTransformation ReferenceId="CreateSubjectClaimFromAlternativeSecurityId" /> </OutputClaimsTransformations> <UseTechnicalProfileForSessionManagement ReferenceId="SM-SocialLogin" /> </TechnicalProfile> </TechnicalProfiles> </ClaimsProvider>
将 client_id 的值替换为你之前记录的 LinkedIn 应用程序的客户端 ID。
保存文件。
添加声明转换
LinkedIn 技术配置文件要求将 ExtractGivenNameFromLinkedInResponse 和 ExtractSurNameFromLinkedInResponse 声明转换添加到 ClaimsTransformations 列表。 如果未在文件中定义 ClaimsTransformations 元素,请添加父 XML 元素,如下所示。 声明转换还需要定义一个名为“nullStringClaim”的新声明类型。
将 BuildingBlocks 元素添加到 TrustFrameworkExtensions.xml 文件顶部附近。 有关示例,请参阅 TrustFrameworkBase.xml。
<BuildingBlocks>
<ClaimsSchema>
<!-- Claim type needed for LinkedIn claims transformations -->
<ClaimType Id="nullStringClaim">
<DisplayName>nullClaim</DisplayName>
<DataType>string</DataType>
<AdminHelpText>A policy claim to store output values from ClaimsTransformations that aren't useful. This claim should not be used in TechnicalProfiles.</AdminHelpText>
<UserHelpText>A policy claim to store output values from ClaimsTransformations that aren't useful. This claim should not be used in TechnicalProfiles.</UserHelpText>
</ClaimType>
</ClaimsSchema>
<ClaimsTransformations>
<!-- Claim transformations needed for LinkedIn technical profile -->
<ClaimsTransformation Id="ExtractGivenNameFromLinkedInResponse" TransformationMethod="GetSingleItemFromJson">
<InputClaims>
<InputClaim ClaimTypeReferenceId="givenName" TransformationClaimType="inputJson" />
</InputClaims>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="nullStringClaim" TransformationClaimType="key" />
<OutputClaim ClaimTypeReferenceId="givenName" TransformationClaimType="value" />
</OutputClaims>
</ClaimsTransformation>
<ClaimsTransformation Id="ExtractSurNameFromLinkedInResponse" TransformationMethod="GetSingleItemFromJson">
<InputClaims>
<InputClaim ClaimTypeReferenceId="surname" TransformationClaimType="inputJson" />
</InputClaims>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="nullStringClaim" TransformationClaimType="key" />
<OutputClaim ClaimTypeReferenceId="surname" TransformationClaimType="value" />
</OutputClaims>
</ClaimsTransformation>
</ClaimsTransformations>
</BuildingBlocks>
添加用户旅程
此时,标识提供者已设置,但还不能在任何登录页中使用。 如果你没有自己的自定义用户旅程,请创建现有模板用户旅程的副本,否则,请继续执行下一步。
- 打开初学者包中的 TrustFrameworkBase.xml 文件。
- 找到并复制包含
Id="SignUpOrSignIn"
的 UserJourney 元素的完整内容。 - 打开 TrustFrameworkExtensions.xml 并找到 UserJourneys 元素。 如果该元素不存在,请添加一个。
- 将复制的 UserJourney 元素的完整内容粘贴为 UserJourneys 元素的子级。
- 对用户旅程的 ID 进行重命名。 例如,
Id="CustomSignUpSignIn"
。
将标识提供者添加到用户旅程
目前你已拥有用户旅程,请将新的标识提供者添加到用户旅程。 首先添加一个“登录”按钮,然后将该按钮链接到某个操作。 该操作是你之前创建的技术配置文件。
在用户旅程中,查找包含
Type="CombinedSignInAndSignUp"
或Type="ClaimsProviderSelection"
的业务流程步骤元素。 这通常是第一个业务流程步骤。 ClaimsProviderSelections 元素包含用户可以用来登录的标识提供者列表。 元素的顺序将决定向用户显示的登录按钮的顺序。 添加 ClaimsProviderSelection XML 元素。 将 TargetClaimsExchangeId 的值设置为易记名称。在下一个业务流程步骤中,添加 ClaimsExchange 元素。 将 ID 设置为目标声明交换 ID 的值。将 TechnicalProfileReferenceId 的值更新为之前创建的技术配置文件的 ID 。
下面的 XML 演示了使用标识提供者进行用户旅程的前两个业务流程步骤:
<OrchestrationStep Order="1" Type="CombinedSignInAndSignUp" ContentDefinitionReferenceId="api.signuporsignin">
<ClaimsProviderSelections>
...
<ClaimsProviderSelection TargetClaimsExchangeId="LinkedInExchange" />
</ClaimsProviderSelections>
...
</OrchestrationStep>
<OrchestrationStep Order="2" Type="ClaimsExchange">
...
<ClaimsExchanges>
<ClaimsExchange Id="LinkedInExchange" TechnicalProfileReferenceId="LinkedIn-OAuth2" />
</ClaimsExchanges>
</OrchestrationStep>
配置信赖方策略
信赖方策略(例如 SignUpSignIn.xml)指定 Azure AD B2C 将执行的用户旅程。 在信赖方内查找 DefaultUserJourney 元素。 更新 ReferenceId,使其与已在其中添加标识提供者的用户旅程 ID 匹配。
在以下示例中,对于 CustomSignUpSignIn
用户旅程,将 ReferenceId 设置为 CustomSignUpSignIn
:
<RelyingParty>
<DefaultUserJourney ReferenceId="CustomSignUpSignIn" />
...
</RelyingParty>
上传自定义策略
- 登录 Azure 门户。
- 在门户工具栏中选择“目录 + 订阅”图标,然后选择包含 Azure AD B2C 租户的目录。
- 在 Azure 门户中,搜索并选择“Azure AD B2C”。
- 在“策略”下,选择“Identity Experience Framework”。
- 选择“上传自定义策略”,然后上传已更改的两个策略文件,其顺序为:先上传扩展策略(例如
TrustFrameworkExtensions.xml
),然后上传信赖方策略(例如SignUpSignIn.xml
)。
测试自定义策略
- 选择信赖方策略,例如
B2C_1A_signup_signin
。 - 对于“应用程序”,请选择前面注册的 Web 应用程序。 “回复 URL”应显示为
https://jwt.ms
。 - 选择“立即运行”按钮。
- 在注册或登录页面上,选择“LinkedIn”以使用 LinkedIn 帐户登录。
如果登录过程是成功的,则你的浏览器会被重定向到 https://jwt.ms
,其中显示 Azure AD B2C 返回的令牌内容。
从 v1.0 迁移到 v2.0
LinkedIn 最近已将其 API 从 v1.0 更新到 v2.0。 若要将现有配置迁移到新配置,请根据以下部分的信息更新技术配置文件中的元素。
替换 Metadata 中的项
在 TechnicalProfile 的现有 Metadata 元素中,更新以下项中的下列 Item 元素:
<Item Key="ClaimsEndpoint">https://api.linkedin.com/v1/people/~:(id,first-name,last-name,email-address,headline)</Item>
<Item Key="scope">r_emailaddress r_basicprofile</Item>
更改为:
<Item Key="ClaimsEndpoint">https://api.linkedin.com/v2/me</Item>
<Item Key="scope">r_emailaddress r_liteprofile</Item>
向 Metadata 添加项
在 TechnicalProfile 的 Metadata 中,添加以下 Item 元素:
<Item Key="external_user_identity_claim_id">id</Item>
<Item Key="BearerTokenTransmissionMethod">AuthorizationHeader</Item>
<Item Key="ResolveJsonPathsInJsonTokens">true</Item>
更新 OutputClaims
在 TechnicalProfile 的现有 OutputClaims 中,更新以下项中的下列 OutputClaim 元素:
<OutputClaim ClaimTypeReferenceId="givenName" PartnerClaimType="firstName" />
<OutputClaim ClaimTypeReferenceId="surname" PartnerClaimType="lastName" />
更改为:
<OutputClaim ClaimTypeReferenceId="givenName" PartnerClaimType="firstName.localized" />
<OutputClaim ClaimTypeReferenceId="surname" PartnerClaimType="lastName.localized" />
添加新的 OutputClaimsTransformation 元素
在 TechnicalProfile 的 OutputClaimsTransformations 中,添加以下 OutputClaimsTransformation 元素:
<OutputClaimsTransformation ReferenceId="ExtractGivenNameFromLinkedInResponse" />
<OutputClaimsTransformation ReferenceId="ExtractSurNameFromLinkedInResponse" />
定义新的声明转换和声明类型
在上一个步骤中,你添加了需要定义的新声明转换。 若要定义声明转换,请将它们添加到 ClaimsTransformations 列表中。 如果未在文件中定义 ClaimsTransformations 元素,请添加父 XML 元素,如下所示。 声明转换还需要定义一个名为“nullStringClaim”的新声明类型。
应将 BuildingBlocks 元素添加到文件顶部附近。 请将 TrustframeworkBase.xml 作为示例查看。
<BuildingBlocks>
<ClaimsSchema>
<!-- Claim type needed for LinkedIn claims transformations -->
<ClaimType Id="nullStringClaim">
<DisplayName>nullClaim</DisplayName>
<DataType>string</DataType>
<AdminHelpText>A policy claim to store unuseful output values from ClaimsTransformations. This claim should not be used in a TechnicalProfiles.</AdminHelpText>
<UserHelpText>A policy claim to store unuseful output values from ClaimsTransformations. This claim should not be used in a TechnicalProfiles.</UserHelpText>
</ClaimType>
</ClaimsSchema>
<ClaimsTransformations>
<!-- Claim transformations needed for LinkedIn technical profile -->
<ClaimsTransformation Id="ExtractGivenNameFromLinkedInResponse" TransformationMethod="GetSingleItemFromJson">
<InputClaims>
<InputClaim ClaimTypeReferenceId="givenName" TransformationClaimType="inputJson" />
</InputClaims>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="nullStringClaim" TransformationClaimType="key" />
<OutputClaim ClaimTypeReferenceId="givenName" TransformationClaimType="value" />
</OutputClaims>
</ClaimsTransformation>
<ClaimsTransformation Id="ExtractSurNameFromLinkedInResponse" TransformationMethod="GetSingleItemFromJson">
<InputClaims>
<InputClaim ClaimTypeReferenceId="surname" TransformationClaimType="inputJson" />
</InputClaims>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="nullStringClaim" TransformationClaimType="key" />
<OutputClaim ClaimTypeReferenceId="surname" TransformationClaimType="value" />
</OutputClaims>
</ClaimsTransformation>
</ClaimsTransformations>
</BuildingBlocks>
获取电子邮件地址
在将 LinkedIn 从 v1.0 迁移到 v2.0 的过程中,需要再次调用另一个 API 才能获得电子邮件地址。 如果需要在注册过程中获取电子邮件地址,请执行以下操作:
完成上述步骤以允许 Azure AD B2C 与 LinkedIn 联合,这样用户就能登录。 在联合身份验证过程中,Azure AD B2C 会接收 LinkedIn 的访问令牌。
将 LinkedIn 访问令牌保存到声明中。 请参阅此处的说明。
添加以下可向 LinkedIn 的
/emailAddress
API 发出请求的声明提供程序。 若要针对此请求授权,需要 LinkedIn 访问令牌。<ClaimsProvider> <DisplayName>REST APIs</DisplayName> <TechnicalProfiles> <TechnicalProfile Id="API-LinkedInEmail"> <DisplayName>Get LinkedIn email</DisplayName> <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> <Metadata> <Item Key="ServiceUrl">https://api.linkedin.com/v2/emailAddress?q=members&projection=(elements*(handle~))</Item> <Item Key="AuthenticationType">Bearer</Item> <Item Key="UseClaimAsBearerToken">identityProviderAccessToken</Item> <Item Key="SendClaimsIn">Url</Item> <Item Key="ResolveJsonPathsInJsonTokens">true</Item> </Metadata> <InputClaims> <InputClaim ClaimTypeReferenceId="identityProviderAccessToken" /> </InputClaims> <OutputClaims> <OutputClaim ClaimTypeReferenceId="email" PartnerClaimType="elements[0].handle~.emailAddress" /> </OutputClaims> <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" /> </TechnicalProfile> </TechnicalProfiles> </ClaimsProvider>
将以下业务流程步骤添加到用户旅程,以便在用户使用 LinkedIn 登录时触发 API 声明提供程序。 请确保相应地更新
Order
号。 紧接着可触发 LinkedIn 技术配置文件的业务流程步骤添加此步骤。<!-- Extra step for LinkedIn to get the email --> <OrchestrationStep Order="3" Type="ClaimsExchange"> <Preconditions> <Precondition Type="ClaimsExist" ExecuteActionsIf="false"> <Value>identityProvider</Value> <Action>SkipThisOrchestrationStep</Action> </Precondition> <Precondition Type="ClaimEquals" ExecuteActionsIf="false"> <Value>identityProvider</Value> <Value>linkedin.com</Value> <Action>SkipThisOrchestrationStep</Action> </Precondition> </Preconditions> <ClaimsExchanges> <ClaimsExchange Id="GetEmail" TechnicalProfileReferenceId="API-LinkedInEmail" /> </ClaimsExchanges> </OrchestrationStep>
在注册期间从 LinkedIn 获取电子邮件地址的操作是可选的。 如果你选择不从 LinkedIn 获取电子邮件,但要求用户在注册过程中提供一个,则用户需要手动输入电子邮件地址并对其进行验证。
如果需要通过完整的示例来了解某个使用 LinkedIn 标识提供者的策略,请参阅自定义策略初学者包。
从 v1.0 迁移到 v2.0
LinkedIn 最近已将其 API 从 v1.0 更新到 v2.0。 在迁移过程中,Azure AD B2C 只能获取 LinkedIn 用户在注册期间提供的全名。 如果电子邮件地址是注册期间收集的属性之一,则用户必须手动输入该电子邮件地址并对其进行验证。