我在this example之后使用MSAL设置了Azure AD B2C。用户可以使用Facebook登录,我获得了一个用户对象,一切都很好。 现在我想检索属性,如Country,City等。这些属性在Azure AD B2C属性中定义。
我需要图谱API吗?我试过调用graph.microsoft.com,但是我收到了令牌错误。我已经阅读了创建app registration所需的文章,但是当我使用该应用程序ID而不是在Azure AD B2C中创建的应用程序时,它会抛出一个错误,我需要使用在B2C门户下创建的应用程序ID
在B2C的应用程序中,我无法配置我想要访问Graph API。
我们有一个C#API,我可以在那里实现这个逻辑。这是要走的路吗?理想情况下,我想直接从客户那里做到。
这是如何协同工作的。我已经阅读了大部分类似的问题,但找不到相同的问题。
答案 0 :(得分:1)
至少对于当前登录用户的属性,有一种方法不需要Graph API。配置 sign_in 和 sign_up 策略后,您可以配置成功验证后通过令牌返回的声明。 请注意,此方法仅适用于当前登录的用户。如果您需要有关其他用户的信息,请使用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中的数据属性传递它。
答案 1 :(得分:1)
您定义的所有属性都应显示在idtoken中,可直接从您的客户端访问。有关客户端上的idtoken解析逻辑的一个示例,请参阅https://github.com/Azure-Samples/active-directory-b2c-xamarin-native/blob/master/UserDetailsClient/UserDetailsClient/MainPage.xaml.cs。
答案 2 :(得分:0)
@vibronet和@regnauld的答案帮助很大!我已将登录/注册策略配置为在声明中包含属性。但是使用MSAL JS时的访问令牌是加密的。因此,必须使用this example取消加密:
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。