基于 asp.net core cliam 的授权抛出“HTTP 错误 400。请求标头的大小太长。”当设置大量索赔时

Posted

技术标签:

【中文标题】基于 asp.net core cliam 的授权抛出“HTTP 错误 400。请求标头的大小太长。”当设置大量索赔时【英文标题】:asp.net core cliam based authorization throw "HTTP Error 400. The size of the request headers is too long." when large number of claim is set 【发布时间】:2021-07-24 16:48:36 【问题描述】:

我已经在我的 asp.net core 2.1 站点中实现了声明基础授权。它是一个ERP,有很多部分。每个部分都有查看、添加、编辑、删除等权限。 假设如果我有 100 个部分,那么它将是大约 400 个索赔。

角色可以拥有任何或所有声明。当用户具有具有所有权限的角色时,即该角色的 [AspNetRoleClaims] 表中的 400 行说“管理员”角色。当用户说“admin”具有“Administrator”角色尝试登录时,他/她会得到

错误请求 - 请求太长

HTTP 错误 400。请求标头的大小太长。

这是因为保存授权信息的cookie超过了浏览器支持的长度。

大约 281 行,随着更多模块的添加,这将在不久的将来增加。

有什么办法可以解决这个问题。或者当我必须处理大量许可时的任何解决方法。即每个控制器操作可能有不同的授权策略。

或者如果我们可以将这些授权信息保存在数据库或会话中而不是 cookie 中。

有没有办法获得大量许可但不使用那么多的索赔政策。

我们是否可以仅在用户浏览特定控制器/操作时强制检查声明,而不是将所有权限信息保存在 cookie 中。

任何建议都会有所帮助。谢谢

【问题讨论】:

您是否将整个 OIDC 令牌存储在您的 cookie 中?这或许可以解释 您所说的“声明基础授权”是什么意思? "每个部分都有查看、添加、编辑、删除等权限。假设如果我有 100 个部分,那么它将是大约 400 个声明。" - 如果你有细粒度的权限,那么你不应该使用字符串。使用打包格式。 当我试图缩小自己的 cookie 时,我为 ASP.NET Core 编写了另一种票证格式。它不适合安全应用程序(由于CRIME/BREACH),但您可能会发现它很有用:github.com/Jehoel/aspnetcore-auth-cookie-optimizations - 它使我的 cookie 从 7KB 减少到 2KB。 @Dai 你所说的打包格式是什么意思。你的意思是我应该使用整数而不是字符串作为声明值。 【参考方案1】:

听起来您正在使用字符串来存储权限 - 而且您拥有很多细粒度的权限。更糟糕的是,ASP.NET Core 2.x(默认情况下)将使用the full WS-* string type name(ClaimValueTypes.String == "http://www.w3.org/2001/XMLSchema/#string")存储String-typed 声明,这太糟糕了......我不知道它是如何通过代码审查的, 待定)。

首先,如果您始终为每个项目(ViewAddEditDelete)恰好有 4 个布尔权限值,那么您可以将其打包成 2 位,这样您就可以每个字节存储 4 个区域 - 因此 400 个区域将占用 100 个字节(假设您可以通过顺序索引识别它们 - 如果您在应用程序代码中生成映射,这是可行的)。

由于这涉及自定义票证格式,您需要:

子类Microsoft.AspNetCore.Authentication.TicketSerializer。 子类Microsoft.AspNetCore.DataProtection.SecureDataFormat<AuthenticationTicket>IPostConfigureOptions<CookieAuthenticationOptions> 中设置自定义序列化程序。

正如我在评论中所写的,当我试图缩小自己的 cookie 时,我为 ASP.NET Core 编写了另一种票证格式。 It isn't suitable for secure applications when GZip compression is enabled (due to CRIME/BREACH) 但您可能会发现它可以作为编写自己的序列化程序的起点:https://github.com/Jehoel/aspnetcore-auth-cookie-optimizations(它使我的 cookie 从 7KB 减少到 2KB)。

【讨论】:

众所周知和常见的声明名称和类型由 1 字节整数表示,而不是它们的完整字符串表示形式。你的意思是它只适用于众所周知的声明,而不是在声明名称不常见的情况下。 嗨,当我们浏览特定的控制器/动作时,有什么方法可以检查运行时的权限,而不是提前在 cookie 中保存权限。 @dilli.shrestha 这与您提出的问题完全不同。 @dilli.shrestha 如果您打算使用我的代码,请仔细阅读:您可以将自己的声明名称和类型添加到代码手册中。 OptimizedTicketDataFormat.ChunkSize ,不包含定义。对不起,我写在这里而不是你的回购。你能告诉我,这是什么,“ChunkSize”。 “OptimizedTicketDataFormat”类中似乎缺少它

以上是关于基于 asp.net core cliam 的授权抛出“HTTP 错误 400。请求标头的大小太长。”当设置大量索赔时的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET Core WebApi Jwt 基于角色的授权不起作用

使用 Azure AD 的 Asp.net core mvc 基于角色的授权

如何在 ASP.NET Core 中基于 appsettings 有条件地使用授权

EF Core 中的 ASP.NET Core 5 MVC 和 Identity - 基于资源的授权

ASP.NET Core认证授权方案

当基于角色的授权失败时,asp.net core 2.0 应用程序崩溃