Подтвердить что ты не робот

Как удалить существующую заявку из ClaimsPrinciple?

Я создаю инструмент разработчика для олицетворения Roles для сайта интрасети, чтобы позволить разработчикам быстро действовать как любой Role по мере необходимости. Определенные роли Developer, Team Lead, Team Member, Engineering, Marketing, Guest, и инструмент на веб-странице делает вызов веб-Api для добавления или удаления Claim... ну, я могу добавить, но не могу найти, где .RemoveClaim(claim) или .TryRemoveClaim(claim), чтобы получить эту работу. Должен ли я создавать собственный менеджер заявок, чтобы получить эту функциональность, или я что-то пропустил?

Я смотрел System.Security.Claims, и почти все остальное работает очень просто и нет ссылки что нужно много работать, чтобы делать то, что мне нужно.

Я использую VS 2013/Web Api2 с .NET 4.5.1.

Сторона веб-сайта просто использует простой вызов ajax для функций PUT и DELETE, пока я не получу это, чтобы работать так, как я хочу. Из Controller мой код cs выглядит так:

    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;
        }
    }

PUT работает отлично, проблема с частью кода DELETE моего кода... Я хочу использовать код user.RemoveClaim(claim); или что-то вроде этого... Я не понимаю, почему я могу 't в соответствии с MSDN, и я не могу найти какой-либо пример кода для удаления претензии.

4b9b3361

Ответ 1

Вы должны использовать идентификатор для добавления или удаления претензии. Попробуйте добавить заявку.

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

Чтобы удалить заявку,

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);

Кстати, лучше использовать User у вашего контроллера вместо HttpContext.Current.User.

Ответ 2

Что-то еще, что важно добавить, - это убедиться, что вы не пытаетесь перебирать коллекцию претензий и удалять элементы. Я просто наткнулся на ковыльный код, написанный кем-то другим, и сначала я не видел проблему, пока не перешагнул ее.

Багги-код:

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

Результат заключался в том, что претензии были непоследовательно удалены из списка. Простое решение проблемы состоит в том, чтобы перебирать список претензий, а не самих претензий, и удалять их следующим образом:

        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);
            }
        }

Никогда не рекомендуется перебирать коллекцию и добавлять или удалять элементы. В зависимости от ситуации вы увидите спорадические ошибки и различные результаты, а в некоторых случаях, например, итерацию элементов в файлах HttpContext.Current.Items, вы увидите спорадические ошибки в отношении модифицируемой коллекции.