azure - 使用 Azure AD B2C 自定义身份提供程序 (OpenID Connect) 映射声明

标签 azure azure-active-directory azure-ad-b2c identityserver3

虽然我已经很好地设置了所有声明映射,因此它们与我们的 Identity Server 3 发布的映射相匹配,但我们似乎在 Azure AD 端没有这些值。姓名和电子邮件是可以用作示例的声明。奇怪的是,这种情况只发生在自定义身份提供商(Open ID Connect)中,而例如 Facebook 内置身份提供商运行良好并接受从 IdP 收到的那些声明。有人做过这个工作吗?

[已编辑] 此外,我还尝试通过此处建议的自定义策略来实现此目的:How to store claims from IdentityServer 3 in Azure AD B2C or just include it in tokens issued by AAD B2C 。现在,我面临另一个问题,即通过使用自定义策略将 AAD B2C 简单地连接到 Identity Server 3。这是来自 TrustFrameworkExnsion.xml 的 TechnicalProfile 定义:

<TechnicalProfile Id="IdentityServerProfile">
    <DisplayName>IdentityServer</DisplayName>
    <Description>Login with your IdentityServer account</Description>
    <Protocol Name="OpenIdConnect"/>
    <OutputTokenFormat>JWT</OutputTokenFormat>
    <Metadata>
        <Item Key="METADATA">https://{identity_server_hostname}/identity/.well-known/openid-configuration</Item>
        <Item Key="ProviderName">https://{identity_server_hostname}/identity</Item>
        <Item Key="client_id">00000000-0000-0000-0000-000000000000</Item>
        <Item Key="IdTokenAudience">00000000-0000-0000-0000-000000000000</Item>
        <Item Key="response_types">code</Item>
        <Item Key="scope">openid profile customScope</Item>
        <Item Key="UsePolicyInRedirectUri">false</Item>
        <Item Key="AccessTokenResponseFormat">json</Item>
        <Item Key="HttpBinding">POST</Item>
    </Metadata>
    <CryptographicKeys>
        <Key Id="client_secret" StorageReferenceId="B2C_1A_IdentityServerAppSecret"/>
    </CryptographicKeys>
    <OutputClaims>      
        <OutputClaim ClaimTypeReferenceId="authenticationSource" DefaultValue="IdentityServer" />
        <OutputClaim ClaimTypeReferenceId="displayName" PartnerClaimType="name" />
        <OutputClaim ClaimTypeReferenceId="identityProvider" DefaultValue="tid" />
        <OutputClaim ClaimTypeReferenceId="socialIdpUserId" PartnerClaimType="sub" />
    </OutputClaims>
    <OutputClaimsTransformations>
        <OutputClaimsTransformation ReferenceId="CreateRandomUPNUserName"/>
        <OutputClaimsTransformation ReferenceId="CreateUserPrincipalName"/>
        <OutputClaimsTransformation ReferenceId="CreateAlternativeSecurityId"/>
    </OutputClaimsTransformations>
    <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop"/>
</TechnicalProfile>

基本上,在 IdentityServer 端进行身份验证后,我被重定向回初始化登录的网页,然后收到此错误: AADB2C:发生异常。 相关 ID:6797f691-4adb-4963-ad12-f31add3e1919 时间戳:2018-08-23 08:42:54Z

在分析 AAD B2C 上给定相关 ID 的日志时,我没有发现任何有用的信息可以引导我找到可能的解决方案。

最佳答案

昨天,在安静地花了很长时间尝试了这么多不同的事情之后,我终于意识到为什么我们没有向客户收回所有 claim 。它们实际上并不存在于身份 token 中,而仅存在于访问 token 中。 AAD B2C 使用第一个身份 token ,同时执行自定义策略中定义的映射,这就是重点。最后我不得不在 IdentityServer3 端做一些小的改变(看看下面的代码)。

这就是负责发出声明并生成身份和访问 token 的类现在的样子:

public class CustomClaimsProvider : DefaultClaimsProvider

{ 私有(private)只读 IIndex ClaimDefinitions;

public CustomClaimsProvider(
    IUserService users,
    IIndex<string, IClaimsDefinition> claimDefinitions)
    : base(users)
{
    this.claimDefinitions = claimDefinitions;
}

public override async Task<IEnumerable<Claim>> GetIdentityTokenClaimsAsync(
   ClaimsPrincipal subject,
   Client client,
   IEnumerable<Scope> scopes,
   bool includeAllIdentityClaims,
   ValidatedRequest request)
{
    var claims = await base.GetIdentityTokenClaimsAsync(subject, client, scopes, includeAllIdentityClaims, request).ConfigureAwait(false);
    return GetAdditionalClaims(scopes, claims);
}

public override async Task<IEnumerable<Claim>> GetAccessTokenClaimsAsync(
    ClaimsPrincipal subject,
    Client client,
    IEnumerable<Scope> scopes,
    ValidatedRequest request)
{
    var claims = await base.GetAccessTokenClaimsAsync(subject, client, scopes, request).ConfigureAwait(false);
    return GetAdditionalClaims(scopes,  claims);
}

private IEnumerable<Claim> GetAdditionalClaims(IEnumerable<Scope> scopes, IEnumerable<Claim> claims)
{
    var scopesList = scopes.ToList();
    var claimsList = claims.ToList();

    foreach (var scope in scopesList.Select(x => x.Name))
    {
        if (claimDefinitions.TryGetValue(scope, out IClaimsDefinition claimDef))
        {
            claimsList.AddRange(claimDef.GetClaims(claims));
        }
    }

    return claimsList;
}

}

因此,要点是,如果您希望将一些附加声明作为身份 token 的一部分,您还应该重写从 DefaultClaimsProvider 派生的类中的 GetIdentityTokenClaimsAsync 方法。

非常感谢 Microsoft 支持,它为我解决问题提供了很多帮助。

关于azure - 使用 Azure AD B2C 自定义身份提供程序 (OpenID Connect) 映射声明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51832358/

相关文章:

Azure Active Directory B2C 限制从其他设备登录

Azure AD B2C MFA 和可信设备

azure - 在 Azure Functions 中将共享程序集的依赖项放置在何处

azure - 如何配置手动预配的 Azure 托管磁盘以用作 Kubernetes 持久卷?

azure - Powershell - New-AzureRmADServicePrincipal - 获取 secret 属性不起作用?

azure - Azure Active Directory easy auth/.auth/me 的权限错误返回 401

azure - Az CLI - 注册 Azure AD B2C 应用程序

c# - Azure 是否有开箱即用的 key 分布式锁定方式?

azure - 如何在 Window Azure 中以编程方式获取区域列表

azure - 有什么方法可以查看内置用户流所指的基本 v1 策略吗?