Объявление Azure возвращает роли в утверждениях, но User.IsInRole возвращает false
Есть идеи, что может быть причиной этого? Я могу видеть утверждения в User.Claims. Единственное, о чем я могу думать, это то, что утверждения от рекламных ролей Azure возвращаются не так, как проверяет IsInRole()?
User.IsInRole возвращает false
[Startup.Auth] [3]
Просто чтобы уточнить, я возвращаю роли, но думаю, что они не добавляются в список требований правильно, и я не могу понять, почему. Nerith IsInRole или [Authorize(Roles="...")] правильно проверит утверждения о ролях.
3 ответа
Любое из этих изменений работало на меня:
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"
},
Необходимо указать имя типа утверждений, который содержит роли. Как это:
TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
RoleClaimType = "roles"
},
После долгих поисков я обнаружил, в чем проблема для нас, и некоторые из этих ответов верны, но только если вы не настроили свою службу приложений для включения Azure AD.
Если вы сделаете это, 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);
}
}
Если у вас возникла та же проблема, что и у меня, я создал собственный класс AuthorizeAttribute и забыл переопределить функцию AuthorizeCore. Добавление кода ниже решило проблему для меня.
//Core authentication, called before each action
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
return base.AuthorizeCore(httpContext);
}
Add Validate Issuer= false;
TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = false,
NameClaimType = "name",
RoleClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role"
}