asp.net-mvc - net - identity roles vs claims
AutorizaciĆ³n basada en roles con IdentityServer4 (3)
Cambiar new Claim("role","FreeUser")
a una new Claim(ClaimTypes.Role, "FreeUser")
O crea una política como esta:
services.AddAuthorization(options =>
{
options.AddPolicy("FreeUser", policy => policy.RequireClaim("role", "FreeUser"));
});
y úsala:
Authorize[(Policy = "FreeUser")]
Estoy tratando de implementar "Autorización basada en roles" utilizando IdentityServer4 para dar acceso a mi API en función de las funciones de los usuarios.
Por ejemplo, quiero tener dos roles para el usuario, es decir, FreeUser y PaidUser, y quiero dar acceso a la API a través del atributo Authorize Attribute usando [Authorize (Roles = "FreeUser")], amablemente ayúdenme, ¿cómo puedo lograr esto? .
Tengo la siguiente estructura de solución:
- IdentityServer
- WebApi
- Cliente Javascript
He registrado mi cliente de Javascript de la siguiente manera:
new Client
{
ClientId = "js",
ClientName = "javascript client",
AllowedGrantTypes = GrantTypes.Implicit,
AllowAccessTokensViaBrowser= true,
RedirectUris = {"http://localhost:5004/callback.html"},
PostLogoutRedirectUris = {"http://localhost:5004/index.html"},
AllowedCorsOrigins = {"http://localhost:5004"},
AllowedScopes =
{
StandardScopes.OpenId.Name,
StandardScopes.Profile.Name,
"api1",
"role",
StandardScopes.AllClaims.Name
}
}
Alcances
return new List<Scope>
{
StandardScopes.OpenId,
StandardScopes.Profile,
new Scope
{
Name = "api1",
Description = "My API"
},
new Scope
{
Enabled = true,
Name = "role",
DisplayName = "Role(s)",
Description = "roles of user",
Type = ScopeType.Identity,
Claims = new List<ScopeClaim>
{
new ScopeClaim("role",false)
}
},
StandardScopes.AllClaims
};
Usuarios
return new List<InMemoryUser>
{
new InMemoryUser
{
Subject = "1",
Username = "alice",
Password = "password",
Claims = new List<Claim>
{
new Claim("name", "Alice"),
new Claim("website", "https://alice.com"),
new Claim("role","FreeUser")
}
},
new InMemoryUser
{
Subject = "2",
Username = "bob",
Password = "password",
Claims = new List<Claim>
{
new Claim("name", "Bob"),
new Claim("website", "https://bob.com"),
new Claim("role","PaidUser")
}
}
};
WebApi Startup.cs
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
app.UseCors("default");
app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
{
Authority = "http://localhost:5000",
ScopeName = "api1",
// AdditionalScopes = new List<string> { "openid","profile", "role" },
RequireHttpsMetadata = false
});
app.UseMvc();
}
Controlador web Api
namespace Api.Controllers
{
[Route("[controller]")]
public class IdentityController : ControllerBase
{
[HttpGet]
[Authorize(Roles = "PaidUser")]
public IActionResult Get()
{
return new JsonResult(from c in User.Claims select new { c.Type, c.Value });
}
[Authorize(Roles = "FreeUser")]
[HttpGet]
[Route("getfree")]
public IActionResult GetFreeUser()
{
return new JsonResult(from c in User.Claims select new { c.Type, c.Value });
}
}
}
Javascript Client app.js Aquí estoy intentando iniciar sesión en el usuario a través de IdentityServer y hacer una solicitud de API.
var mgr = new Oidc.UserManager(config);
mgr.getUser().then(function (user) {
if (user) {
log("User logged in", user.profile);
} else {
log("User is not logged in.");
}
});
function login() {
mgr.signinRedirect();
}
function api() {
mgr.getUser().then(function (user) {
var url = "http://localhost:5001/identity/getfree";
var xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.onload = function () {
log(xhr.status, JSON.parse(xhr.responseText));
};
xhr.setRequestHeader("Authorization", "Bearer " + user.access_token);
xhr.send();
});
}
function logout() {
mgr.signoutRedirect();
}
El flujo de inicio de sesión funciona bien y puedo iniciar sesión correctamente, y puedo recibir el rol en el token de acceso.
Cuando realizo una solicitud a la API haciendo clic en el botón (Llamar Api), aparece el siguiente error.
Dado que no ha proporcionado el objeto config para el cliente javascript, supongo que tiene el alcance configurado de la siguiente manera.
scope:"openid profile api1 role"
Creo que la razón principal de su problema es que el reclamo de funciones no está incluido en su token de acceso.
Agregue reclamo de función al ámbito api1 de la siguiente manera para incluirlo en el token de acceso.
new Scope
{
Name = "api1",
DisplayName = "API1 access",
Description = "My API",
Type = ScopeType.Resource,
IncludeAllClaimsForUser = true,
Claims = new List<ScopeClaim>
{
new ScopeClaim(ClaimTypes.Name),
new ScopeClaim(ClaimTypes.Role)
}
}
Puede leer mi respuesta aquí para obtener ayuda para solucionar el problema. implementando roles en el servidor de identidad 4 con identidad asp.net
La solución de trabajo completa está aquí. https://github.com/weliwita/IdentityServer4.Samples/tree/40844310
Escribí una muestra en esta publicación
Identity Server 4: agregar reclamos de token de acceso
He probado con Roles y también puedo usar [Autorizar (Role = "SuperAdmin, Admin")] tanto en la aplicación web del cliente como en la aplicación API.