我正在尝试关注OpenID Connect best practices。对于从应用程序调用API的简单方案,OpenID Connect建议传递访问令牌(不包括用户身份),如果某些点的API需要用户身份,则应调用OpenID Connect提供程序的/userinfo
端点。
所以问题是:它是在API中获取用户身份的最佳方式吗?
假设我有一个名为CreateOrderForCurrentUser()
的终点,所以每次任何用户调用此api我需要调用/userinfo
端点时,调用api似乎要花费太多。
请问任何想法。
这似乎与我的问题有点相似:Clarification on id_token vs access_token
他回答评论:https://community.auth0.com/t/clarification-on-token-usage/8447#post_2
我的理解意味着:在Access令牌(自定义声明)中放置一些身份声明并依赖于API中的声明。
但它仍然没有意义。 OIDC坚持不使用Access令牌作为身份,现在我们将在访问令牌中添加身份声明。任何人都可以澄清一下吗?
ID_Token用于您的客户端应用程序告诉应用程序您是谁,ID令牌的受众是您的客户端应用程序的ID,具有访问令牌,API /资源知道是否有权访问API并执行范围指定的特定操作已被授予。
默认情况下,它将在访问令牌(子声明)中包含用户标识符,因此您应该在调用CreateOrderForCurrentUser
函数时知道哪个用户。您可以根据需要自定义访问令牌以包含更多与用户相关的声明。但我建议简化访问令牌,您可以使用访问令牌通过调用用户的API端点来获取用户信息。
我在Auth0 Community问了同样的问题,并且有一个关于它的讨论可能对那些有同样问题的人有帮助。
我在这里复制相同的答案:
你是正确的,你不应该使用访问令牌作为身份证明,但在你到达你的API之前,你应该已经验证了用户并为他们收到了id_token。如果您已经通过OIDC对用户进行了身份验证,据我所知,向访问令牌添加自定义声明以将数据传递到API没有任何问题。您的API还可以使用客户端凭据授予类型从Auth0中提取数据。
我:
我正在寻找最好的做法。我想确保向访问令牌添加身份声明,并依赖于API中的内容并没有破坏任何内容并且基于最佳实践,或者最佳实践总是在API中调用/userinfo
端点并且不依赖于Access令牌身份声明。
API不知道身份验证过程,也不关心。任何一个如何将签名的Access令牌传递给API,它都会被接受。现在从API的角度来看,在Access Token中依赖身份声明的正确方法是什么?我有疑问。但如果我们可以忽略每次调用/userinfo
终点,我会很高兴。
我可以就这个问题分享一些(希望)知情的观点,但是请你带着他们的问题和你不同意的问题,或者你认为不够清楚。当它带有软件时,魔鬼就是细节,而且在安全领域更是如此,所以你需要考虑最佳实践,因为大多数场景可能会推荐这些最佳实践,而且风险可能会降低。这并不意味着别的什么都不可能。
例如,虽然建议确实在对API的请求中使用访问令牌,但这并不意味着没有特定的场景,从技术上讲,也可以发送ID令牌。
专注于你的特定问题,从最后一个问题开始(3);我们不应该比较HOK和访问令牌,因为它们不在同一级别。换句话说,您可以质疑在您的场景中是否应该使用承载令牌或HOK令牌,并使用链接页面的术语,您将在两个令牌配置文件之间进行选择,其中每个令牌具有不同的特征。
此时,作为API授权的一部分由Auth0服务发出的访问令牌是承载访问令牌,因此如果使用Auth0服务,该问题只有一个答案。
跳到第一个问题;并不是你不能将ID令牌传递给API,只是那些足够的场景受到更多约束。例如,发出ID令牌,客户标识符作为观众;拥有多个客户端应用程序是很常见的,因此您只需将API与您拥有的客户端应用程序相关联,因为假设您将验证ID令牌的受众,您的API现在需要知道每个客户端的标识符。
对于问题(2),我假设如果您可以在访问令牌中包含声明,那么对于为什么调用/ userinfo也感兴趣。我相信这很大程度上取决于要求和/或个人偏好。此时,向自定义API发出访问令牌时支持的唯一格式是JWT格式。
上面的意思是你有一个自包含的令牌,一旦发布API,它可以主要独立验证,这在可伸缩性方面是很好的,因为API不需要(频繁)外部调用进行验证。
但是,立即自包含意味着您直接包含在令牌中的任何数据都将被视为令牌本身生命周期的真实性。如果API直接调用/ userinfo甚至是Management API,那么您将以网络开销为代价确保新数据。
总之,在我个人看来,网络调用和嵌入式声明之间的选择更多地与您感兴趣的数据的特征相关,仅从最佳实践的角度来看。
最后,即使没有添加任何自定义声明,服务与自定义API关联发出的访问令牌也已传达用户身份。特别是,如果访问令牌是JWT,则子声明将包含唯一标识最终用户的标识符,该最终用户授权当前应用程序代表他们调用API。