0

我已经按照这个示例设置了带有 MSAL 的 Azure AD B2C 。用户可以用Facebook登录,我得到一个用户对象,一切都好。现在我想检索属性,例如 Country、City 等。这些是在 Azure AD B2C 属性中定义的。

我需要 Graph API 吗?我试过调用 graph.microsoft.com,但我得到了令牌错误。我已阅读需要创建应用程序注册的文章,但是当我使用该应用程序 ID 而不是在 Azure AD B2C 中创建的应用程序 ID 时,它会引发错误,我需要使用在 B2C 门户下创建的应用程序 ID。

在 B2C 的应用程序中,我无法配置我想要访问 Graph API。

我们确实有一个 C# API,我可能可以在其中实现这个逻辑。这是要走的路吗?理想情况下,我想直接从客户那里完成。

这是如何一起工作的,这一切都非常令人困惑。我已经阅读了大多数类似的问题,但找不到相同的问题。

4

3 回答 3

1

您定义的所有属性都应该出现在 idtoken 中,可以从您的客户端直接访问。请参阅https://github.com/Azure-Samples/active-directory-b2c-xamarin-native/blob/master/UserDetailsClient/UserDetailsClient/MainPage.xaml.cs以获取直接在客户端上解析逻辑的一个示例。

于 2017-08-08T18:05:23.427 回答
1

至少对于当前登录用户的属性,有一种不需要 Graph API 的方法。当您配置您的登录注册策略时,您可以配置在成功验证后通过令牌返回的声明。请注意,此方法仅适用于当前登录的用户。如果您需要有关其他用户的信息,您应该使用 graphAPI。

本质上,在您的应用程序中,您可以从当前ClaimsPrincipal对象中检索这些声明/属性。

例如,这是一个类,我在当前应用程序中使用它,它允许我访问用户所需的所有信息。甚至还有一个自定义用户属性(phone_number):

public class ApplicationUser : IApplicationUser
{
    private readonly IHttpContextAccessor contextAccessor;

    public ApplicationUser(IHttpContextAccessor contextAccessor)
    {
        this.contextAccessor = contextAccessor;
    }

    public virtual bool IsAuthenticated => contextAccessor.HttpContext?.User?.Identity.IsAuthenticated ?? false;

    public string Id => GetAttribute(ClaimTypes.NameIdentifier);
    public string GivenName => GetAttribute(ClaimTypes.GivenName);
    public string Surname => GetAttribute(ClaimTypes.Surname);
    public string DisplayName => GetAttribute("name");
    public bool IsNewUser => GetBoolAttribute("newUser");
    public string Email => GetAttribute("emails");
    public string PhoneNumber => GetAttribute("extension_PhoneNumber");

    public bool IsCurrentUser(string userId)
    {
        return userId != null && Id != null && userId.Equals(Id, StringComparison.CurrentCultureIgnoreCase);
    }

    private string GetAttribute(string claim)
    {
        return IsAuthenticated ? contextAccessor.HttpContext.User.GetClaim(claim) : null;
    }

    public bool GetBoolAttribute(string claim)
    {
        bool output;
        bool.TryParse(GetAttribute(claim), out output);
        return output;
    }
}

public static class ClaimsPrincipalExtensions
{
    public static string GetClaim(this ClaimsPrincipal principal, string claim)
    {
        if (principal == null)
        {
            throw new ArgumentNullException(nameof(principal));
        }

        if (string.IsNullOrWhiteSpace(claim))
        {
            throw new ArgumentNullException(nameof(claim));
        }

        return principal.FindFirst(claim)?.Value;
    }
}

该界面允许我在需要的地方注入它:

public interface IApplicationUser
{
    string Id { get; }
    string GivenName { get; }
    string Surname { get; }
    string DisplayName { get; }
    bool IsNewUser { get; }
    string Email { get; }
    string PhoneNumber { get; }

    bool IsCurrentUser(string userId);
}

编辑:您可以通过创建一个 rest api 端点并使用 ajax 调用它来轻松地将此信息传输到客户端。或者用 html 中的数据属性传递它。

于 2017-08-08T09:34:33.440 回答
0

@vibronet 和 @regnauld 的回答很有帮助!我已将登录/注册策略配置为在声明中具有属性。但是使用 MSAL JS 时的访问令牌是加密的。所以,不得不使用这个例子来解密它:

private setAuthenticated(accessToken: string) {
  // Update the UI.
  this.isAuthenticated = true;
  this.identity = Msal.Utils.extractIdToken(accessToken) as AuthIdentity;
  this.identity.displayName = this.identity.given_name + ' ' + this.identity.family_name;
  console.log(this.identity);
}

然后它起作用了!我可以在控制台中查看所有属性(地址、显示名称等),而无需使用 Graph API。

于 2017-08-08T23:21:18.523 回答