C# Azure Ad在声明中返回角色,但User.IsInRole返回false
你知道是什么引起的吗?我可以在用户声明中看到声明。我唯一能想到的是来自Azure Ad角色的声明与IsInRole()检查的声明不同 [Startup.Auth][3]C# Azure Ad在声明中返回角色,但User.IsInRole返回false,c#,azure,roles,azure-active-directory,C#,Azure,Roles,Azure Active Directory,你知道是什么引起的吗?我可以在用户声明中看到声明。我唯一能想到的是来自Azure Ad角色的声明与IsInRole()检查的声明不同 [Startup.Auth][3] 我只是想澄清一下,我正在找回角色,但我认为他们没有被正确地添加到索赔清单中,我无法找出原因。Nerith IsInRole或[Authorize(Roles=“…”)将正确检查角色声明。您需要指定包含角色的声明类型的名称。像这样: TokenValidationParameters = new TokenValidation
我只是想澄清一下,我正在找回角色,但我认为他们没有被正确地添加到索赔清单中,我无法找出原因。Nerith IsInRole或[Authorize(Roles=“…”)将正确检查角色声明。您需要指定包含角色的声明类型的名称。像这样:
TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
RoleClaimType = "roles"
},
这些变化中的任何一个都对我有用:
TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = false,
RoleClaimType = System.Security.Claims.ClaimTypes.Role
},
或
如果您遇到与我相同的问题,我创建了一个自定义AuthorizeAttribute类,但忘记重写AuthorizeCore函数。添加下面的代码为我解决了这个问题
//Core authentication, called before each action
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
return base.AuthorizeCore(httpContext);
}
经过大量挖掘,我发现了我们的问题所在,其中一些答案是正确的,但前提是您尚未将应用程序服务配置为启用Azure广告。 如果执行此操作,将不使用代码中定义的RoleClaimType,并将其设置为默认值“http://schemas.microsoft.com/ws/2008/06/identity/claims/role,但您所有的角色声明都将是“角色” 解决方案基本上是将声明从“角色”复制到ClaimsIdentity.RoleClaimType。解决方案已在上文中找到并提到 解决方案:
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);
}
}
public void ConfigureAuth(IAppBuilder应用程序)
{
//此设置确保使用下面指定的TokenValidationParameters.RoleClaimType
JwtSecurityTokenHandler.DefaultMapInboundClaims=false;
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(新的CookieAuthenticationOptions());
app.UseOpenIdConnectAuthentication(
新的OpenIdConnectAuthenticationOptions
{
//遗漏了一些东西
TokenValidationParameters=新的TokenValidationParameters()
{
validateisuer=true,
RoleClaimType=“角色”
}
}
);
//配置out-OnAuth方法以修复角色的身份验证后
应用程序使用((上下文,下一步)=>
{
OnAuth(上下文);
返回next.Invoke();
});
应用程序UseStageMarker(PipelineStage.PostAuthentication);
}
OnAuth上的私有静态void(IOwinContext上下文)
{
if(ClaimsPrincipal.Current.Identity.IsAuthenticated)
{
var claimsPrincipal=claimsPrincipal.Current;
var claimsIdentity=claimsPrincipal.Identity作为claimsIdentity;
var approvles=新列表();
//本地开发人员是对的
if(claimsIdentity.RoleClaimType==“角色”)
返回;
//查找所有具有“角色”的声明,并添加具有正确RoleClaimType的副本声明。
foreach(claimsPrincipal.FindAll(“角色”)中的索赔)
approvles.Add(新索赔(claimsIdentity.RoleClaimType,索赔.Value));
如果(近似计数>0)
增加索赔(批准);
}
}
Joshua您是否手动创建该索赔?通常,角色的声明类型不是“角色”,这可能是User.IsInRole找不到它的原因。不,这是从Azure Ad创建并返回的。让我怀疑这是否是一个bug?通常是JwtSecurityTokenHandler。ValidateToken(…)将类型为“角色”的声明映射到“../claims/role”,因此IsInRole可以工作。您是如何从JWT创建ClaimsPrincipal的?@JoshuaHolden您使用的是MVC应用程序吗?你是在谈论azure应用程序角色还是azure广告组?你看到这个答案了吗?我已经在这么做了,但这并不能解决我的问题。我正在取回角色,但它们没有被正确映射,也没有被IsInRole或Authorize属性识别。我也在这里发布了一个基本示例:请查看@Phyo Win response,RoleClaimType=“roles”
似乎不再起作用了。RoleClaimType=System.Security.Claims.ClaimTypes.Role
为我修复了它!你救了我的同伙。荣誉
Add Validate Issuer= false;
TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = false,
NameClaimType = "name",
RoleClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role"
}
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);
}
}