Azure B2C: How do I get "group" claim in JWT token
Plan Z it is I'm afraid. I don't know why they don't return it, but it's currently marked as planned on their Feedback Portal (it's the highest rated item).
This is how I'm doing it. Querying the groups when the user is authenticated, you can do it your way as well - just query as and when you need to. Depends on your use case.
public partial class Startup{ public void ConfigureAuth(IAppBuilder app) { app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType); app.UseKentorOwinCookieSaver(); app.UseCookieAuthentication(new CookieAuthenticationOptions { LoginPath = new PathString("/account/unauthorised"), CookieSecure = CookieSecureOption.Always, ExpireTimeSpan = TimeSpan.FromMinutes(20), SlidingExpiration = true, CookieHttpOnly = true }); // Configure OpenID Connect middleware for each policy app.UseOpenIdConnectAuthentication(CreateOptionsFromPolicy(Globals.SignInPolicyId)); } private OpenIdConnectAuthenticationOptions CreateOptionsFromPolicy(string policy) { return new OpenIdConnectAuthenticationOptions { // For each policy, give OWIN the policy-specific metadata address, and // set the authentication type to the id of the policy MetadataAddress = string.Format(Globals.AadInstance, Globals.TenantName, policy), AuthenticationType = policy, AuthenticationMode = AuthenticationMode.Active, // These are standard OpenID Connect parameters, with values pulled from web.config ClientId = Globals.ClientIdForLogin, RedirectUri = Globals.RedirectUri, PostLogoutRedirectUri = Globals.RedirectUri, Notifications = new OpenIdConnectAuthenticationNotifications { AuthenticationFailed = AuthenticationFailed, SecurityTokenValidated = SecurityTokenValidated }, Scope = "openid", ResponseType = "id_token", // This piece is optional - it is used for displaying the user's name in the navigation bar. TokenValidationParameters = new TokenValidationParameters { NameClaimType = "name", } }; } private async Task SecurityTokenValidated(SecurityTokenValidatedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> token) { var groups = await _metaDataService.GetGroups(token.AuthenticationTicket.Identity.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value); if (groups?.Value != null && groups.Value.Any()) { foreach (IGroup group in groups.Value.ToList()) { token.AuthenticationTicket.Identity.AddClaim( new Claim(ClaimTypes.Role, group.DisplayName, ClaimValueTypes.String, "GRAPH")); } } } // Used for avoiding yellow-screen-of-death private Task AuthenticationFailed(AuthenticationFailedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> notification) { notification.HandleResponse(); if (notification.Exception.Message == "access_denied") { notification.Response.Redirect("/"); } else { notification.Response.Redirect("/error?message=" + notification.Exception.Message); } return Task.FromResult(0); }}
My GetGroups
method just queries the getMemberGroups
method on the Users API
Then I have a simple helper method to determine whether the user is in a role:
public static bool UserIsInRole(IPrincipal user, string roleName){ var claims = user.Identity as ClaimsIdentity; if (claims == null) return false; return claims.FindAll(x => x.Type == ClaimTypes.Role).Any(x => x.Value == roleName);}