为什么 OAuth2 中的 machine-to-machine 交互在不提供 client_secret 的情况下不允许 refresh_token 授权?

Why does machine-to-machine interaction in OAuth2 disallow the refresh_token grant without providing the client_secret?

我们正在为 API 实施 JWT-based 身份验证,使用 Keycloak 作为身份提供者和令牌端点。

我们发现 OAuth2 的想法很有吸引力,因为它减少了 long-lived 凭据在网络上传输的需要。他们可以使用客户端 ID 和密码来请求访问令牌,而不是向我们发出 end-users 一个 API 密钥,他们会为他们发送给我们的每个请求放入 header寿命相对较短。

错误地 假设客户端也会收到一个刷新令牌并能够使用它(而不是使用客户端密钥)获得新的 access/refresh 令牌对.这将进一步减少客户端密钥在网络上来回传输的需要。


这是我最初推理的一些背景:

在这种情况下,嗅探网络流量的攻击者将非常幸运地看到静态凭据已通过并且凭据(无论是静态还是刷新)的泄露非常明显,因为合法客户端会注意到其刷新令牌不再有效。


但是,根据我在标准中收集到的信息,在 OAuth2 下发生 machine-to-machine 交互的普遍接受的方式是使用客户端凭据授予类型,它不会 return 刷新令牌和客户端必须每 10-15 分钟左右请求一个新的访问令牌及其凭据。

这让我感到困惑:这基本上不是另一种复杂的基本身份验证类型,我们在其中通过可能不安全的网络重复发送静态凭据吗?当然,大多数请求都是使用访问令牌完成的,但是攻击者肯定会知道每 10-15 分钟就会将静态凭据发送到授权服务器。

是否有另一种方法可以进行 machine-to-machine 交互,这种方法可以更好地防止攻击者设法嗅探我们的流量?更具体地说,避免或主要避免发送静态凭据。

关于您关于另一种进行 machine-to-machine 交互的方法的问题,这种方法可以更好地防止攻击者设法嗅探我们的流量,客户端可以使用其他身份验证方法。

默认客户端身份验证方法基于共享密钥,在 OAuth 2.0 规范中称为客户端密钥。必须将客户端 ID 和密码发送到身份验证服务器以获取访问令牌。每次先前发布的访问令牌过期时都必须发生这种情况。这增加了客户机密暴露的风险。此方法不需要刷新令牌,因为客户端正在为自己获取令牌。此方法通过 SSL 执行,可降低暴露的风险。此外,主动 IP 监控进一步降低了泄露客户端机密的风险。如果请求是从一个不可见的 IP 发出的,则客户端密码可能会失效。

但是,比共享客户端密钥更安全的替代方法是私钥和签名的 JWT 身份验证。客户端使用私钥并在 JWT 令牌中签署一组断言。此 JWT 与令牌请求一起发送。 JWT 的寿命极短,到期时间设置为距问题几秒钟。 auth 服务器配置了相应的 public 密钥,并且能够验证 JWT 签名,从而验证客户端的请求。此 JWT 是一次性使用的令牌,应包含唯一的令牌 ID。 Auth 服务器可以保留唯一的 JWT id 直到过期以防止令牌重放。

除了短暂的 JWT 之外,还可以实施客户端 IP 监控,以便客户端仅被允许使用来自一组已建立的 IP 地址或来自先前观察到的一组 IP 地址的密钥。

OAuth 2.0 还允许客户端通过在 TLS 握手期间提交给 auth 服务器的 X.509 证书进行身份验证。

https://datatracker.ietf.org/doc/html/rfc8705