无论流程如何,生成的 MAC 令牌都是相同的:一个对称密钥和一个 id 被发送给客户端一次。这个秘密再也不会通过网络发送了。
客户端不验证令牌*,客户端使用它就像使用不记名令牌一样,只是秘密不是通过网络发送的,因此不能泄露:
+--------------+ +--------------+
| |>------Request with authenticator------>| |
| | | Resource |
| Client | | server |
| |<--------Requested resource------------<| |
| | +--------------+
+--------------+ ^
^ |
| |
| |
| |
| MAC algorithm
MAC algorithm over key+params
over key+params
客户端使用密钥和一些参数(包括令牌 ID、随机数、时间戳和一些其他数据)构建计算 MAC 的身份验证器,并将其附加到请求中。
资源服务器(或 RS 用来验证令牌的第三个服务器)知道这个密钥,因此它使用相同的参数执行与客户端相同的计算。如果一切都匹配,则继续请求。
服务器还负责通过检查时间戳和防止 nonce-reuse 来防止重放攻击。
这可以防止令牌泄露的许多情况:TLS 错误配置/错误、攻击者控制的端点找到进入客户端数据库的方式等。
关于你的第三个问题,是和不是。OAuth2 MAC 规范草案为 JWT 定义了一些声明,以使用JWT 对发送和使用 MAC 令牌所需的信息进行编码,但 OpenID Connect 仍在使用不记名令牌。
不记名令牌的主要问题是客户端的开发人员必须非常了解安全性,并且其安全性完全依赖于 TLS。
很多人误解了最后这句话,并得出结论认为 OAuth2 本质上是不安全的、无用的和注定要失败的。更糟糕的是,他们在谈话、发帖和评论中盲目地重复这种结论,只会让人们感到困惑。
OAuth2 对于某些用例非常好,但对于其他用例则很糟糕。它需要对一些安全原则有很好的理解。它也需要一些妥协。但它就在那里,它正在工作,它解决了一个非常困难的问题。
MAC 的使用从未标准化,但草案非常好并且易于实施。今天也有几种选择。
(*):我的意思是客户端不执行 MAC 验证。当然,观众和其他领域仍然应该得到验证。