Home > Mobile >  Removing Claims from ClaimPrincipal in C#
Removing Claims from ClaimPrincipal in C#

Time:07-30

I am kind of scratching my head to resolve this issue where I have to remove all the Claims in one go. When I use the below code, I get this error Collection was modified; enumeration operation may not execute

Since, I am changing/modifying the value from the enumerator that I am currently looping through, therefore, I am getting this error. Any idea how can I resolve this issue. I have used the below code:

private static readonly string[] claimTypes=
    {
        ClaimTypes.Role,
        ClaimTypes.UserSpecific.IdleSessionTimeout,
        ClaimTypes.CustomerSpecific.ApplicationId,
        ClaimTypes.CustomerSpecific.CustomerId,
        ClaimTypes.CustomerSpecific.CustomerName,
        ClaimTypes.CustomerSpecific.CurrencyCode,
        ClaimTypes.CustomerSpecific.Locale,
        ClaimTypes.CustomerSpecific.TimeZone,
        ClaimTypes.CustomerSpecific.ReportingUnitId
    };


public static void RemoveClaimsFor(this ClaimsPrincipal principal, params string[] claimTypes)
    {
        if (principal == null) throw new ArgumentNullException(nameof(principal));


        foreach (var identity in principal.Identities)
        {
            foreach (var claim in identity.FindAll(claim => claimTypes.Any(type => type == claim.Type)))
            {
                identity.TryRemoveClaim(claim);
            }
        }
    }

Since this was giving error so I thought of using the below code. but this also does not work.

public static void RemoveClaimsFor(this ClaimsPrincipal principal, params string[] claimTypes)
    {
        if (principal == null) throw new ArgumentNullException(nameof(principal));
        var claimNamedList = principal.Identities.Select(x=>x.Claims.Select(y=>y.Type).ToList());
        foreach (var identity in principal.Identities)
        {
            var claimNameList = identity.FindAll(claim => claimTypes.Any(type => type == claim.Type));
            foreach (var name in claimNameList)
            {
                var aa = principal.Identities.Select(x => x.Claims.Where(b => b.Type == name.Type));
                identity.TryRemoveClaim(name);
            }
        }

    }

CodePudding user response:

In order to solve this, you need to create a new collection that you enumerate:

public static void RemoveClaimsFor(this ClaimsPrincipal principal, params string[] claimTypes)
{
    if (principal == null) throw new ArgumentNullException(nameof(principal));


    foreach (var identity in principal.Identities)
    {
        var claimsToRemove = identity
          .FindAll(claim => claimTypes.Any(type => type == claim.Type))
          .ToArray();
        foreach (var claim in claimsToRemove)
        {
            identity.TryRemoveClaim(claim);
        }
    }
}

By using ToArray (or ToListor another To* method), the results of the enumeration are stored in a new collection that you can enumerate over. When removing items, this does not affect the newly created collection so the error will be gone.

  • Related