Azure B2C:如何获得“组"身份?在JWT令牌中索赔 [英] Azure B2C: How do I get "group" claim in JWT token

查看:70
本文介绍了Azure B2C:如何获得“组"身份?在JWT令牌中索赔的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Azure B2C中,我过去可以通过遵循

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 Azure manager (https://manage.windowsazure.com)
  • Register my application with B2C
  • Download the B2C manifest for the application
  • In the manifest, change the "groupMembershipClaims" entry to

"groupMembershipClaims":"SecurityGroup",

"groupMembershipClaims": "SecurityGroup",

  • 再次上传更改后的B2C清单
  • 在过去(大约一个月前),这种方法运行良好,但现在已经不行了.详情请见下文...

    This has worked well in the past (about a month ago, I believe...) but it doesn't anymore. See below for details...

    遵循上面的已知有效配方.

    Follow the known-good recipe above.

    不幸的是,它不再起作用-当此客户端尝试通过B2C对我进行身份验证时,出现以下错误:

    Unfortunately that doesn't work anymore - I get the following error when this client tries to authenticate me with B2C:

    AADB2C90068:提供的ID为'032fe196-e17d-4287-9cfd-25386d49c0d5'的应用程序对此服务无效.请使用通过B2C门户创建的应用程序,然后重试."

    AADB2C90068: The provided application with ID '032fe196-e17d-4287-9cfd-25386d49c0d5' is not valid against this service. Please use an application created via the B2C portal and try again"

    好的,很公平-他们正在将我们转移到新的门户网站.

    OK, fair enough - they're moving us to the new Portal.

    使用新的门户网站遵循旧的良好食谱.

    Follow the good old recipe, using the new Portal.

    但这也不起作用-当我进入下载清单"部分时,我找不到任何访问清单的方法(Google告诉我它可能已经消失了……).

    But that doesn't work either - when I get to the "download manifest" part, I cannot find any way to access the manifest (and Googling tells me it's probably gone for good...).

    有点绝望的是,我尝试混合使用计划A和计划B:使用新的门户注册应用程序,然后使用旧的Azure管理器更改清单.

    Getting a little desperate, I tried mixing plans A and B: register the app using the new Portal, then change the manifest using the old Azure Manager.

    但是没有运气-当我尝试上传清单时,它失败并显示消息

    But no luck - when I try to upload the manifest, it fails with the message

    ParameterValidationException =提供了无效的参数; BadRequestException =此版本不允许更新到聚合应用程序.

    ParameterValidationException=Invalid parameters provided; BadRequestException=Updates to converged applications are not allowed in this version.

    计划Z:使用Graph API检索组成员资格数据

    只需放弃组"声明-相反,每当我需要组信息时,只需使用Graph API查询B2C服务器即可.

    Plan Z: Use the Graph API to retrieve group membership data

    Just give up the "group" claim - instead, whenever I need group info, just query the B2C server using the Graph API.

    我真的很不想这样做-它将破坏访问令牌的自包含性,并使系统变得非常混乱".

    I really, really don't want to do this - it would ruin the self-contained-ness of the access token, and make the system very "chatty".

    但是我在这里将其作为计划Z包含在内,只是为了说:是的,我知道该选项存在,不,我还没有尝试过-我宁愿不这样做.

    But I've included it as a plan Z here, just to say: yes, I know the option exists, no I haven't tried it - and I'd prefer not to.

    这几天我如何在我的JWT令牌中获得团体"索赔?

    How do I get the "group" claim in my JWT token these days?

    推荐答案

    恐怕是Z计划.我不知道为什么他们不返回它,但是它目前是

    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);
        }
    }
    

    我的GetGroups方法仅查询 getMemberGroups方法

    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);
    }
    

    这篇关于Azure B2C:如何获得“组"身份?在JWT令牌中索赔的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆