OAuth 2.0指定了两个client types:
和第2.2节说:
客户端标识符不是 秘密;它暴露给资源所有者,不得使用 单独进行客户端身份验证。
虽然我很清楚公共客户主要用于隐式流程,但这比看起来更多。在执行身份验证代码流时,我们首先使用client_id请求授权端点,不需要密码。然后,在获得用户同意和授权代码后,我们request the token endpoint。根据规范,我们可以在没有client_secret的情况下请求此端点:
client_id REQUIRED, if the client is not authenticating with the authorization server as described in Section 3.2.1.
如果客户端类型是机密或客户端是客户端 凭证(或指定的其他身份验证要求), 客户端必须按照描述使用授权服务器进行身份验证 在第3.2.1节中。
...
授权服务器必须:
... o ensure that the authorization code was issued to the authenticated confidential client, or if the client is public, ensure that the code was issued to "client_id" in the request,
所以基本上这部分说我们能够在没有客户端秘密的情况下请求此端点。现在,除了那些可能包含在请求中的刷新令牌之外,它没有说什么。
因为刷新令牌通常是持久的凭证 请求额外访问令牌,刷新令牌绑定到 发给它的客户。如果客户类型是机密或 客户端已获得客户端凭据(或已分配其他凭据) 身份验证要求),客户端必须通过身份验证 授权服务器,如第3.2.1节中所述。
所以基本上我们可以在没有客户端身份验证的情况下刷新访问令牌。
现在,令我困惑的是implicit flow不允许发出刷新令牌:
授权服务器不得发出刷新令牌。
它没有明确说明为什么我们不能这样做,只是我们不允许这样做。我的理由是这是不允许的,因为客户端不可信任。但由于公共客户端允许授权代码流,为什么我们实际上需要隐式流,如果使用公共客户端可以实现相同的事情,还有获取刷新令牌?
如果有人能澄清这一点,我会很高兴。
答案 0 :(得分:1)
允许您在没有客户秘密的情况下请求/刷新访问令牌,后果自负。或者我们可以说这取决于您的安全要求。该规范仅阐明了对机密客户端的客户端身份验证,基本上,如果客户端是机密的。它必须由服务器验证。
对于公共客户,规范规定:
授权服务器不得发布客户端密码或其他密码 本机应用程序或基于用户代理的客户端凭据 客户端身份验证的应用程序客户端。
因此,公共客户甚至都没有要进行身份验证的秘密。然后规范还说:
当无法进行客户端身份验证时,授权服务器 应该采用其他方式来验证客户的身份- 例如,通过要求注册客户端重定向URI 或邀请资源所有者确认身份。一个有效的 重定向URI不足以验证客户端的身份 在请求资源所有者授权时,但可以用来 防止在以后向假冒客户交付凭据 获得资源所有者的授权。
您也可以查看PKCE。
回到您的问题,我认为您是误会:
根据规范,我们可以在没有client_secret的情况下请求此端点。
不太正确,您必须对机密客户端进行身份验证,并且不能使用客户端机密(它没有一个)来对公共客户端进行身份验证。
授权服务器不得发布刷新令牌。
我认为这完全是安全问题。在隐式授予中,我们在一个不安全的环境下运行。公开刷新令牌可能会损害您的系统,因为我们已经以这种授权类型公开了访问令牌(请阅读security consideration for access token)。
但是,由于公共客户端可以使用授权代码流,因此,如果可以用公共客户端实现相同的事情,并获得刷新令牌,为什么我们实际上需要隐式流?
它们用于完全不同的用例。来自https://oauth.net/2/grant-types/implicit/
Implicit授予类型是可由公共客户端使用的简化流程,其中访问令牌无需额外的授权代码交换步骤即可立即返回。
通常不建议使用隐式流(某些服务器完全禁止该流)。自最初编写规范以来,行业最佳实践已发生变化,建议公共客户应使用带有PKCE扩展名的授权代码流。
最后,我建议您使用this site来更好地了解不同的赠款类型。