Je crée un outil de développement pour usurper l'identité de Roles
pour un site intranet afin de permettre aux développeurs d'agir rapidement en tant que Role
selon les besoins. Les rôles définis sont Developer, Team Lead, Team Member, Engineering, Marketing, Guest
Et un outil sur la page Web appelle un Web Api pour ajouter ou supprimer le Claim
... eh bien je peux ajouter mais je n'arrive pas à trouver où la fonction .RemoveClaim(claim)
ou .TryRemoveClaim(claim)
est accessible pour que cela fonctionne. Dois-je créer un gestionnaire de réclamations personnalisé pour obtenir cette fonctionnalité ou manque-t-il quelque chose?
J'ai regardé System.Security.Claims et presque tout le reste semble fonctionner très simplement et il n'y a aucune référence à la nécessité d'un travail approfondi pour faire ce dont j'ai besoin.
J'utilise VS 2013/Web Api2 avec .NET 4.5.1.
Le côté du site Web utilise simplement un simple appel ajax pour les fonctionnalités PUT
et DELETE
jusqu'à ce que cela fonctionne comme je le souhaite. Depuis le contrôleur, mon code cs est le suivant:
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;
}
}
Le Put
fonctionne très bien, le problème est avec la partie Delete
de mon code ... Je veux utiliser le code user.RemoveClaim(claim);
ou quelque chose comme ça ... I Je ne vois pas pourquoi je ne peux pas selon MSDN, et je ne trouve aucun exemple de code pour supprimer une revendication.
Vous devez utiliser l'identité pour ajouter ou supprimer une réclamation. Essayez ceci pour ajouter une réclamation.
var user = User as ClaimsPrincipal;
var identity = user.Identity as ClaimsIdentity;
identity.AddClaim(new Claim(ClaimTypes.Role, "somenewrole"));
Pour supprimer une réclamation,
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);
BTW, il est préférable d'utiliser User
depuis votre contrôleur au lieu de HttpContext.Current.User
.
Il est important d'ajouter quelque chose d'autre pour vous assurer que vous n'essayez pas de parcourir la collection de revendications et de supprimer des éléments. Je suis juste tombé sur un code bogué écrit par quelqu'un d'autre, et au début, je n'ai pas vu le problème avant de l'avoir traversé.
Le code buggy était:
foreach (var claim in identity.Claims)
{
var name = claim.Type;
if (!name.Equals("UserAccountId") && !name.Equals("Email") && !name.Equals("TenantIds"))
{
identity.RemoveClaim(claim);
}
}
Le résultat a été que les revendications ont été supprimées de manière incohérente de la liste. La solution simple au problème consiste à parcourir une liste de revendications et non les revendications elles-mêmes, et à les supprimer de cette façon:
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);
}
}
Ce n'est jamais une bonne idée de parcourir une collection et d'ajouter ou de supprimer des éléments. Vous verrez des erreurs sporadiques et des résultats différents selon la situation, et dans certaines circonstances, telles que l'itération sur des éléments dans HttpContext.Current.Items, vous verrez des erreurs sporadiques sur la collection en cours de modification.