net based asp c# asp.net-web-api wif claims-based-identity

c# - based - ¿Cómo elimino un reclamo existente de un ClaimsPrinciple?



web api authentication (2)

Estoy creando una herramienta de desarrollo para suplantar Roles en un sitio de intranet para permitir que los desarrolladores actúen rápidamente como cualquier Role que sea necesario. Los roles definidos son Developer, Team Lead, Team Member, Engineering, Marketing, Guest y una herramienta en la página web realiza una llamada a un Api de Web para agregar o eliminar el Claim ... bueno, puedo agregar pero no puedo encontrarlo para acceder a este .RemoveClaim(claim) o .TryRemoveClaim(claim) se puede acceder. ¿Tengo que crear un administrador de reclamaciones personalizado para obtener esta funcionalidad o me falta algo?

He estado buscando en System.Security.Claims y casi todo lo demás parece funcionar muy directamente y no hay ninguna referencia en cuanto a la necesidad de un trabajo extenso para hacer lo que necesito.

Estoy usando VS 2013 / Web Api2 con .NET 4.5.1.

El lado del sitio web solo usa una simple llamada ajax para PUT y DELETE funcionalidad hasta que esto funcione como quiero. Desde el Controlador, mi código cs es como:

public void Put(int id, [FromBody]string role) { if (FindClaim(role) != null) return; var user = HttpContext.Current.User as ClaimsPrincipal; if (user == null) return; var claimId = new ClaimsIdentity(); claimId.AddClaim(new Claim(ClaimTypes.Role, role)); user.AddIdentity(claimId); } // DELETE api/devroleadjuster/5 public void Delete(int id, [FromBody]string role) { var claim = FindClaim(role); if (claim == null) return; var user = HttpContext.Current.User as ClaimsPrincipal; if (user == null) return; // Why can''t I do this???? user.RemoveClaim(claim); } private Claim FindClaim(string role) { try { var user = HttpContext.Current.User as ClaimsPrincipal; var claim = (from c in user.Claims where c.Value == role select c).Single(); return claim; } catch (InvalidOperationException) { return null; } }

El Put funciona bien, el problema está en la parte Delete de mi código ... Quiero usar el user.RemoveClaim(claim); código o algo así ... No puedo ver por qué no puedo de acuerdo con MSDN, y no puedo encontrar ningún código de ejemplo para eliminar un reclamo.


Debe utilizar la identidad para agregar o eliminar un reclamo. Intenta esto para agregar un reclamo.

var user = User as ClaimsPrincipal; var identity = user.Identity as ClaimsIdentity; identity.AddClaim(new Claim(ClaimTypes.Role, "somenewrole"));

Para eliminar un reclamo,

var user = User as ClaimsPrincipal; var identity = user.Identity as ClaimsIdentity; var claim = (from c in user.Claims where c.Value == "somenewrole" select c).Single(); identity.RemoveClaim(claim);

Por cierto, es mejor usar User desde su controlador en lugar de HttpContext.Current.User .


Otra cosa que es importante agregar es asegurarse de no tratar de iterar sobre la colección de reclamos y eliminar elementos. Me topé con un código de buggy escrito por otra persona, y al principio no vi el problema hasta que lo resolví.

El código de buggy era:

foreach (var claim in identity.Claims) { var name = claim.Type; if (!name.Equals("UserAccountId") && !name.Equals("Email") && !name.Equals("TenantIds")) { identity.RemoveClaim(claim); } }

El resultado fue que las reclamaciones se eliminaron inconsistentemente de la lista. La solución simple al problema es iterar sobre una lista de reclamaciones y no las reclamaciones en sí, y eliminarlas de esa manera:

var claimNameList = identity.Claims.Select(x => x.Type).ToList(); foreach (var name in claimNameList) { if (!name.Equals("UserAccountId") && !name.Equals("Email") && !name.Equals("TenantIds")) { var claim = identity.Claims.FirstOrDefault(x => x.Type == name); if (claim != null) identity.RemoveClaim(claim); } }

Nunca es una buena idea recorrer una colección y agregar o eliminar elementos. Verá errores esporádicos y diferentes resultados dependiendo de la situación, y en algunas circunstancias, como iterar sobre elementos en HttpContext.Current.Items, verá errores esporádicos sobre la colección que se está modificando.