'Why doesn't claims transformation reduce the cookie size?
I am using Azure AD (.net core 2.1) and have registered my app and configured it to return AD groups as claims. I am also using claims transformation to remove all group claims other than the three groups that my app uses, which successfully eliminates over 100 groups. I did this hoping that it would reduce the size of the cookie in subsequent request headers, but this does not appear to be the case.
Whether I use the claims transformation or not, the cookie size is the same:

I know that the claims transformation is working, because I have a simple page that iterates the claims in a list, and it correctly shows only the three groups when I have the filter in place.
As a result of the large cookie, I am getting HTTP 400 - Request too long. I can work around this by modifying the registry on the web server (as suggested elsewhere https://support.microsoft.com/en-us/help/2020943/http-400-bad-request-request-header-too-long-response-to-http-request), but my real question is what is the point of filtering the claims if the size of the cookie remains unchanged?
I would also be interested to know if there is an app setting that I could use to increase the max header size, to avoid having to modify the registry.
I'm not sure if the code is really relevant here, but here are a few snippets:
public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
{
var identity = principal.Identity as ClaimsIdentity;
if (identity != null)
{
var unused = identity.FindAll(GroupsToRemove).ToList();
unused.ForEach(c => identity.TryRemoveClaim(c));
}
return Task.FromResult(principal);
}
The filter is registered as a singleton in Startup.cs:
services.AddSingleton<IClaimsTransformation, FilterGroupClaimsTransformation>();
Solution 1:[1]
Brad answered the question as to why the cookie size did not change by using claims transformation. Here is the code I used to reduce the cookie size, thanks to his suggestion:
In Startup.cs, ConfigureServices()...
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(...)
.AddCookie(options => options.Events.OnSigningIn = FilterGroupClaims);
}
private static Task<ClaimsPrincipal> FilterGroupClaims(CookieSigningInContext context)
{
var principal = context.Principal;
if (principal.Identity is ClaimsIdentity identity)
{
var unused = identity.FindAll(GroupsToRemove).ToList();
unused.ForEach(c => identity.TryRemoveClaim(c));
}
return Task.FromResult(principal);
}
private static bool GroupsToRemove(Claim claim)
{
string[] _groupObjectIds = new string[] { }; // pull from config or whereever
return claim.Type == "groups" && !_groupObjectIds.Contains(claim.Value);
}
For my end solution, I moved the static methods inside another class, but I kept everything inline here for brevity. Cookie size reduced from 6 chunks to 2 with this method.
Solution 2:[2]
For everything that has to do with Identity we must use the Authorization Cookie
using this form, it did not work for me, because it never entered the event OnSigningIn:
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(...)
.AddCookie(options => options.Events.OnSigningIn = FilterGroupClaims);
}
But it inspired me and this form did work for me, it eliminates the claims that I don't need and reduces the Cookie size.
In Startup.cs, ConfigureServices():
//Solved
services.ConfigureApplicationCookie(options =>
{
options.Events.OnSigningIn = async (signinContext) =>
{
var principal = signinContext.Principal;
var identity = principal.Identity as ClaimsIdentity;
foreach (var claim in principal.Claims.ToList())
{
if (claim.Type == ClaimTypes.Role &&
!claim.Value.StartsWith(claim_prefix_to_remove_applicationPrefix)
{
identity.RemoveClaim(claim);
}
}
};
});
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Dominick |
| Solution 2 | Tim |
