Azure B2C: How do I get “group” claim in JWT token

后端 未结 1 1235
我在风中等你
我在风中等你 2020-12-29 06:08

In the Azure B2C, I used to be able to get a \"groups\" claim in my JWT tokens by following Retrieving Azure AD Group information with JWT:

  • Open the old-school
相关标签:
1条回答
  • 2020-12-29 06:27

    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);
    }
    
    0 讨论(0)
提交回复
热议问题