一个角色或用户可以拥有多少个声明?我一直在使用ASP.Net.Core 2.2和AspNet.Core.Identity开发应用程序。一切正常,直到在我的浏览器上进行测试为止。在VS2019中进行调试时,不会出现此类问题。
我部署了我的应用程序以进行进一步测试,并遇到此错误(如下)。我在IE,GC和FF中遇到相同的问题。
HTTP Error 400. The size of the request headers is too long.
我正在使用Roles
和RoleClaims
经过一番挖掘,我发现与角色/声明有关,因为其中有太多的角色/声明会破坏缓存。基本上Identity
尝试将所有声明存储在cookie中,而cookie现在太大了。
Microsoft会给您所有的复杂性只是让浏览器挫败,这真是很奇怪。
所以我的问题是: -如果由于浏览器限制而无法利用角色/声明,那又有什么意义呢? -是否有关于虚构限制的记录(每个角色的最大索偿数)?
答案 0 :(得分:0)
该限制不是虚构的,也不是基于浏览器的。请求限制由服务器设置,是一种安全措施。因此,尝试增加限制确实不是一个好主意。
此外,此处没有关于最大声明数之类的真实指导,因为它基于变量:单个声明的类型和大小以及请求的其他部分,例如可能或可能的其他标头不能在任何给定时间添加。但是,限制通常为8-32K,即使在低端,在达到限制之前,您仍然可以添加很多声明。通常,您还应该考虑传输大小。声明是身份验证票证的一部分,这意味着客户端必须随每个请求转移它们。每个请求8K可能看起来并不多,但在用户会话的整个生命周期中可能会明显增加,尤其是在用户连接速度慢或数据连接受限制的情况下。
总之,您最好在这里做的是减少索赔额。并非所有事情都是必需的,也不应该是要求的。在用户配置文件上存储其他数据并根据需要查询。您绝对应该拥有的唯一声明是诸如ID,用户名/电子邮件和角色之类的关键内容。以后或需要时,其他任何东西都可以随时从备用商店获取。
首先,还有一个选项可以使用备用存储区来实际存储身份验证票证数据。您可以简单地发送一个标识符,然后基于该标识符提取实际数据,而不是像发送会话那样将所有内容作为Cookie一起发送出去,而是类似于会话的工作原理。这是通过创建ITicketStore
的实现并将其设置为CookieAuthenticationOptions.SessionStore
来完成的。有一个old sample for using cache as the store。您可能需要修改新版本的ASP.NET Core的代码。
答案 1 :(得分:0)
只是让您知道,无论我做了什么,我都无法使ITicketStore正常工作。我什至花了几天的时间阅读我在ITicketStore上可以找到的所有文档,但文档记录并不多。这似乎是一个很普遍的问题(Cookie和ITicketStore文档)。
无论如何,我更改了应用程序,以便Asp.Net.Identity只承担用户角色。这样可以解决Cookie大小的问题。
我已经实现了自己的功能来检查角色声明。当发生任何更改时,我觉得哪种方法效果更好,因此无需登录/注销即可获得新声明或撤销现有声明。
我有一个服务函数,它带有一个IdentityUser<AppUser>
和一个Claim名称(字符串)。
_adminService.UserHasClaim(user, ClaimName) // returns true or false if you have that claim or not
我有自己的表,与包含值的AspNetRoleClaims表相同。该表的Asp.Net.Identity版本现在为空,因此cookie不包含任何声明。
public bool UserHasClaim(AppUser user, string claimValue)
{
var claim = (from c in _context.AppUserRoleClaims
join t in _context.AppUserClaimTypes on c.ClaimID equals t.ID
join r in _context.UserRoles on c.RoleId equals r.RoleId
where r.UserId == user.Id && t.ClaimValue == claimValue select c).FirstOrDefault();
return (claim != null);
}
它可能不是完美的或理想的,但它确实有效,我再也没有时间花更多的时间尝试使用身份来解决这个问题。我不认为它是理想的,我可能会稍后再讨论。
很高兴对一个更好的可行解决方案发表评论,但是到目前为止,这就是我解决问题的方式。
所以,继续...