Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么在OAuth2中缓存访问令牌被认为是坏的?_C#_Asp.net Web Api_Oauth 2.0_Token_Owin - Fatal编程技术网

C# 为什么在OAuth2中缓存访问令牌被认为是坏的?

C# 为什么在OAuth2中缓存访问令牌被认为是坏的?,c#,asp.net-web-api,oauth-2.0,token,owin,C#,Asp.net Web Api,Oauth 2.0,Token,Owin,我遵循这篇文章撤销用户访问: 现在,在验证用户之后,我已经发布了一个30分钟的生命周期,如上面文章所示,刷新令牌为1天,但是如果管理员在10分钟内删除该用户,而剩下的20分钟,那么在这种情况下,我需要撤销对该用户的访问。 为了做到这一点,我需要从刷新令牌表中删除该用户条目,以禁止进一步的访问令牌请求,但由于accesstoken过期时间仍有20分钟,所以用户将能够访问完全错误的受保护资源 所以我想实现缓存机制,以便在服务器上缓存访问令牌,并将其保存在数据库中。所以,当该用户被撤销时,我可以简单

我遵循这篇文章撤销用户访问:

现在,在验证用户之后,我已经发布了一个30分钟的生命周期,如上面文章所示,刷新令牌为1天,但是如果管理员在10分钟内删除该用户,而剩下的20分钟,那么在这种情况下,我需要撤销对该用户的访问。 为了做到这一点,我需要从刷新令牌表中删除该用户条目,以禁止进一步的访问令牌请求,但由于accesstoken过期时间仍有20分钟,所以用户将能够访问完全错误的受保护资源

所以我想实现缓存机制,以便在服务器上缓存访问令牌,并将其保存在数据库中。所以,当该用户被撤销时,我可以简单地从缓存和数据库中删除该用户条目,以阻止该用户访问受保护的资源

但下面的2个答案是,oauth2不是这样设计的:

所以我的问题是:

1) 为什么缓存访问令牌不被认为比刷新令牌机制更好,也是一种糟糕的方法

我的第二个问题是基于@Hans Z.给出的以下回答,他在回答中说:

这必然涉及到资源服务器(RS)咨询 授权服务器(AS),这是一个巨大的开销

2) 在撤销用户访问的情况下,为什么RS会咨询AS,因为AS只是为了验证用户并根据此生成访问令牌

3) 本文中只有两个项目:

  • Authentication.api-验证用户并生成访问令牌
  • 资源服务器-借助
    [Authorize]
    属性验证accesstoken

    在上述情况下,哪个是授权服务器

更新:我已决定使用刷新令牌来撤销用户访问权限,以防用户被删除,并且在用户注销时,我将从刷新令牌表中刷新令牌,因为您要求我们希望在用户单击注销后立即注销用户

但这里的问题是,我有250个与用户关联的角色,因此如果我将角色放在accesstoken中,accesstoken的大小将非常大,我们无法从标头传递如此巨大的accesstoken,但我无法查询角色,以便在每次调用端点时验证用户对端点的访问


这是我面临的另一个问题。

这里似乎有两个不同的问题:关于访问令牌和关于角色的大列表

访问令牌

OAuth2被设计为能够处理高负载,这需要一些权衡。特别是,这就是为什么OAuth2一方面明确区分“资源服务器”和“授权服务器”角色,另一方面明确区分“访问令牌”和“刷新令牌”角色的原因。如果对于每个请求,您必须检查用户授权,这意味着您的授权服务器应该能够处理系统中的所有请求。对于高负荷系统,这是不可行的

OAuth2允许您在性能和安全性之间进行以下权衡:授权服务器生成一个访问令牌,该令牌可由资源服务器验证,而无需访问授权服务器(在授权服务器的生命周期内至少不超过一次)。这可以有效地缓存授权信息。因此,通过这种方式,您可以大大减少授权服务器上的负载。缓存的缺点与往常一样:授权信息可能会暂停。通过改变访问令牌的使用寿命,您可以调整性能与安全性之间的平衡

如果您使用微服务体系结构,其中每个服务都有自己的存储,而不访问彼此的存储,那么这种方法也可能会有所帮助

尽管如此,如果您没有太多的负载,并且您只有一个资源服务器,而没有使用不同的技术实现大量不同的服务,那么没有什么可以阻止您对每个请求进行全面的验证。也就是说,是的,您可以将访问令牌存储在DB中,在每次访问资源服务器时对其进行验证,并在删除用户时删除所有访问令牌,等等。但正如@Evk所注意到的,如果这是您的场景,那么OAuth2对您来说是一个过冲

大型角色列表

AFAIUOAuth2没有为用户角色提供显式功能。还有一个“作用域”特性也可能用于角色,它的典型实现是,对于250个角色,它将产生太长的字符串。尽管如此,OAuth2并没有显式地为访问令牌指定任何特定的格式,所以您可以创建一个自定义令牌,将角色信息作为位掩码保存。使用base-64编码,您可以将6个角色转换为一个字符(64=2^6)。因此,250-300个角色将可管理40-50个字符

JWT

因为您可能需要一些定制令牌,所以您可能对aka JWT感兴趣。简言之,JWT允许您指定自定义的额外负载(私有声明)并将您的角色位掩码放在那里

如果您真的不需要OAuth2的任何高级特性(例如作用域),那么实际上可以单独使用JWT而不使用整个OAuth2。尽管JWT令牌应该仅通过其内容进行验证,但您仍然可以将它们存储在本地DB中,并对DB进行额外的验证(正如您将要对access刷新令牌所做的那样)


2017年12月1日更新

如果您想在OAuth基础设施中使用OW,可以通过和中的
AccessTokenFormat
自定义令牌格式,从而提供自定义格式化程序。您还可以覆盖
refreshtTokenFormat

下面的示意图显示了如何将角色声明“压缩”到单个位掩码中:
[Authorize(Roles = "Role1")]
[Route("")]
public IHttpActionResult Get()