我们有一个单页应用程序,它调用我们的后端服务(C#和Python),使用Auth0 SPA流程授权这些请求。
我们的后端服务仅在处理来自SPA用户的请求时向对方发出请求,因此目前我们只是转发SPA请求中的Authorization标头,使用它来授权对每个被叫服务的操作。
我现在想要添加后端处理作业,这些作业将在我们的服务之间发出请求,从而调用现有的端点。这些请求将不会有任何现有的auth标头转发,因此需要构建自己的。
根据Auth0文档here和here,我认为我应该使用客户端凭据授权来授权这些请求,并且我推断我们现有的端点因此需要接受授权的请求两种不同的方式:来自SPA或其他服务。
问题是来自SPA的JWT使用一个密钥签名,而来自服务的JWT使用其各自的密钥签名。我是否正确,我需要配置我的端点,以便他们接受使用任何这些密钥构造的JWT?
所以我的核心问题是:这种理解是否正确,或者我应该以完全不同的方式做到这一点?
详细说明:
我们的端点需要处理的两种类型的授权JWT令牌是:
1来自SPA的要求,包含:
sub: SPA-USER-ID
aud: SPA-CLIENT-ID
使用HS256(由于历史原因)使用我们的SPA客户密码签名。
2个服务到服务请求,包含:
sub: SERVICE-ID@clients
aud: API-ID
scope: ""
使用我们的呼叫服务的客户端密钥使用HS256签署(现在为了简单起见)。
如果一个端点要解码并验证两个请求,首先它会失败,因为'aud'值不同。我认为现有SPA调用的'aud'值是一个错误 - 它应该是接收请求的API的ID。然后两个请求中的'aud'值都是相同的。
接下来的不同之处在于它们每个都使用不同的密钥签名 - SPA或呼叫服务(如果我选择使用RS256作为Auth0推荐的新服务呼叫,则可能使用不同的算法)。
我无法发现明显的方法来修改Python和C#快速入门以接受使用不同键编码的令牌。我正在考虑自己编码,手动尝试一个,如果失败则尝试另一个。我有信心我可以为Python端点授权做这件事,我自己编写了基于使用PyJWT的Auth0快速入门,但不太熟悉我们的C#内容,它也基于Auth0快速入门,但似乎使用了一些内置.NET JWT验证中间件,我完全不确定是否可以通过其内部添加上述功能。
但如果我以正确的方式这样做,那么这肯定是一个常见的要求吗?
道歉,如果这个问题形成得很糟糕,我对auth一无所知,并且正在阅读Auth0 / Oath2文档,以便在我去的时候弄明白。
答案 0 :(得分:3)
(以第三人称回答我自己的问题)
这种理解是否正确,或者我应该以完全不同的方式做到这一点?
问题中概述的整体流程是正确的。然而,存在一个普遍存在的误解:
当服务(或SPA)从Auth0(或任何发行者)请求新访问令牌时,他们提供的密钥通常不是Auth0用于签署返回令牌的密钥。相反,发行者使用受众的密钥(将使用此访问令牌调用的API)。
OP之所以对此感到困惑,是因为他提交的代码,如问题中所述,在请求令牌时错误地传递了SPA本身的“受众”价值。因此,使用SPA的秘密签署所产生的令牌。修复此问题后,要将API ID用作“受众”,则为SPA生成的令牌和为服务到服务调用生成的令牌将全部:
包含audience = API-ID,因此除了'sub'(用户ID)和'scope'(当前未使用)之外,其他所有方面都包含等效的有效负载。
使用观众的API-SECRET与HS256签名。
因此,端点不必检查使用两个不同密钥编码的两种不同类型的令牌。它只需使用自己的“受众”标识符及其自己的密钥来检查传入请求,这将成功解码并验证来自SPA和其他服务的请求。