Azure 广告在声明中返回角色,但 User.IsInRole 返回 false

Posted

技术标签:

【中文标题】Azure 广告在声明中返回角色,但 User.IsInRole 返回 false【英文标题】:Azure Ad Returning Roles in Claims but User.IsInRole returns false 【发布时间】:2016-07-29 00:00:44 【问题描述】:

知道是什么原因造成的吗?我可以在 User.Claims 中看到声明 我能想到的唯一一件事是来自 Azure Ad Roles 的声明与 IsInRole() 检查的声明不同?

CorpAdmin Role showing in claims.

User.IsInRole returns false

[Startup.Auth][3]

澄清一下,我正在恢复角色,但我认为它们没有正确添加到声明列表中,我无法弄清楚原因。 Nerith IsInRole 或 [Authorize(Roles="...")] 将正确检查角色声明。

【问题讨论】:

Joshua 您是否手动创建了该声明?通常角色的声明类型是schemas.microsoft.com/ws/2008/06/identity/claims/role 而不是“角色”这可能是 User.IsInRole 找不到它的原因。 msdn.microsoft.com/en-us/library/… 不,这是从 Azure Ad 创建和返回的。让我怀疑这是否是一个错误? 通常 JwtSecurityTokenHandler.ValidateToken(...) 将类型为“roles”的声明映射到“.../claims/role”,因此 IsInRole 将起作用。您如何从 JWT 创建 ClaimsPrincipal? @JoshuaHolden 您在使用 MVC 应用程序吗?您是在谈论 azure 应用程序角色还是 azure 广告组? 你看这个答案***.com/a/30098192/4167200了吗? 【参考方案1】:

这些更改中的任何一个都对我有用:

            TokenValidationParameters = new TokenValidationParameters()
            
                ValidateIssuer = false,
                RoleClaimType = System.Security.Claims.ClaimTypes.Role
            ,

            TokenValidationParameters = new TokenValidationParameters()
            
                ValidateIssuer = false,
                RoleClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role"
            ,

【讨论】:

RoleClaimType = System.Security.Claims.ClaimTypes.Role 帮我修好了! 你救了我的好朋友。荣誉【参考方案2】:

您需要指定包含角色的声明类型的名称。像这样:

TokenValidationParameters = new TokenValidationParameters

    ValidateIssuer = true,
    RoleClaimType = "roles"
,

【讨论】:

我已经在这样做了,但这并不能解决我的问题。我正在取回角色,但它们没有被正确映射或被 IsInRole 或 Authorize 属性识别。我也在这里发布了基本示例:github.com/Azure-Samples/… 请参阅@Phyo Win 回复,RoleClaimType = "roles" 似乎不再起作用了。【参考方案3】:

经过大量挖掘,我发现问题出在我们身上,其中一些答案是正确的,但前提是您尚未将应用服务配置为启用 Azure AD。

如果您这样做,代码中定义的 RoleClaimType 将不会被使用,它会将其设置为默认值“http://schemas.microsoft.com/ws/2008/06/identity/claims/role”,但是您的所有角色声明都将是“角色”。

解决方案基本上是将声明从“角色”复制到 ClaimsIdentity.RoleClaimType。解决方法在here找到,上面也提到了。

解决方案:

public void ConfigureAuth(IAppBuilder app)

    //This setting ensures that we use the specified TokenValidationParameters.RoleClaimType below
    JwtSecurityTokenHandler.DefaultMapInboundClaims = false;

    app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
    app.UseCookieAuthentication(new CookieAuthenticationOptions());
    app.UseOpenIdConnectAuthentication(
        new OpenIdConnectAuthenticationOptions
        
            //Omitted some stuff
            TokenValidationParameters = new TokenValidationParameters()
            
                ValidateIssuer = true,
                RoleClaimType = "roles"
            
        
    );

    //Configure out OnAuth Method to fix the roles post auth
    app.Use((context, next) =>
    
        OnAuth(context);
        return next.Invoke();
    );
    app.UseStageMarker(PipelineStage.PostAuthenticate);


private static void OnAuth(IOwinContext context)

    if (ClaimsPrincipal.Current.Identity.IsAuthenticated)
    
        var claimsPrincipal = ClaimsPrincipal.Current;
        var claimsIdentity = claimsPrincipal.Identity as ClaimsIdentity;
        var appRoles = new List<Claim>();

        //local dev will be right
        if (claimsIdentity.RoleClaimType == "roles")
            return;

        //Find all the claims with "roles" and add a copy claim with the correct RoleClaimType.
        foreach (Claim claim in claimsPrincipal.FindAll("roles"))
            appRoles.Add(new Claim(claimsIdentity.RoleClaimType, claim.Value));

        if (appRoles.Count > 0)
            claimsIdentity.AddClaims(appRoles);
    

【讨论】:

【参考方案4】:

如果您遇到与我相同的问题,我创建了一个自定义 AuthorizeAttribute 类,但我忘记了重写 AuthorizeCore 函数。添加下面的代码为我解决了这个问题。

    //Core authentication, called before each action
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    
        return base.AuthorizeCore(httpContext);
    

【讨论】:

【参考方案5】:
Add Validate Issuer= false;

TokenValidationParameters = new TokenValidationParameters

    ValidateIssuer = false,
    NameClaimType = "name",
    RoleClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role"

【讨论】:

以上是关于Azure 广告在声明中返回角色,但 User.IsInRole 返回 false的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Azure 广告 B2C 上使用自定义角色?

Azure广告声明-检索用户名

Azure AD - 令牌中缺少角色声明

Azure AD:访问令牌中缺少角色声明

验证 Azure 广告访问令牌时签名无效,但 id 令牌有效

Azure Active Directory RBAC 不返回承载令牌中的角色