Cookie 中存储的声明超出最大请求标头长度

问题描述 投票:0回答:3

我有一个 ASP.NET Core 2.0 网站,使用普通实现使用 Identity 和 cookie(不使用 OpenID Connect)进行身份验证/授权。我有一组 20 个角色,每个角色可能有数百个声明,用于授予访问网站页面/功能的权限(使用 Authorize 来装饰控制器方法)。我希望能够控制对这些页面/功能的访问,而无需每次需要更改时重新编译网站;相反,我允许管理员直接通过网站添加/删除角色声明。由于某种原因,根据投射到用户身份的声明数量,我达到了上限。

我收到错误消息

HTTP Error 400. The size of the request headers is too long

知道为什么我会收到此消息吗?存储/访问这些经过授权使用的声明的最佳实践是什么?

asp.net-core asp.net-core-2.0 claims-based-identity
3个回答
2
投票

在 Windows 服务器上遇到同样的问题。 我不得不求助于注册表设置。

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\HTTP\Parameters

MaxFieldLength (DWORD) 十进制值 65534

MaxRequestBytes (DWORD) 十进制值 16777216

https://support.microsoft.com/en-ca/help/820129/http-sys-registry-settings-for-windows


2
投票

此问题可通过配置 CookieAuthenticationOptions 以使用会话存储来解决。 以下链接详细解释了“ASP.NET Core 中的 Auth Cookies”及其配置选项

点击这里


0
投票

另一种方法是减少您保存的声明数量,按照为什么声明转换不减少 cookie 大小?.

的答案

许多索赔的常见原因是使用 AD 或 AzureAD 或 Entra 身份验证并返回所有用户的安全组。在这种情况下,您可以重新配置应用程序以过滤组或在代码中执行类似的操作:

builder.Services
    .AddAuthentication()
    .AddCookie(o=>o.Events.OnSigningIn = ctx =>
         {
             const string groupType = "http://schemas.xmlsoap.org/claims/Group";
             var groupsICareAbout = new[]{"Group1", "Group2"};
             Predicate<Claim> wantedClaim =
                 c => c.Type != groupType || groupsICareAbout.Contains(c.Value);
             
             foreach (var identity in ctx.Principal?.Identities ?? [])
             {
                 var unused = identity.FindAll(wantedClaim).ToList();
                 unused.ForEach(c => identity.TryRemoveClaim(c));
             }
             return Task.CompletedTask;
         });

如果您使用 AD 身份验证,则要使用的事件是

options.Events.OnSecurityTokenReceived
:

builder.Services.AddAuthentication(sharedOptions =>
       {
           sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
           sharedOptions.DefaultChallengeScheme = WsFederationDefaults.AuthenticationScheme;
       })
        .AddWsFederation(options =>
         {
             options.Wtrealm = builder.Configuration["wsfed:realm"];
             options.MetadataAddress = builder.Configuration["wsfed:metadata"];
             options.Events.OnSecurityTokenReceived= context =>
             {
                 const string groupType = "http://schemas.xmlsoap.org/claims/Group";
                 var groupsICareAbout = new[]{"Group1", "Group2"};
                 Predicate<Claim> wantedClaim =
                     c => c.Type != groupType || groupsICareAbout.Contains(c.Value);
                 
                 foreach (var identity in ctx.Principal?.Identities ?? [])
                 {
                     var unused = identity.FindAll(wantedClaim).ToList();
                     unused.ForEach(c => identity.TryRemoveClaim(c));
                 }
                 return Task.CompletedTask;
             };
         })
         .AddCookie();
© www.soinside.com 2019 - 2024. All rights reserved.