Oauth 我们真的需要客户端密钥来获取PKCE流上的访问令牌吗?
我正在构建2个应用程序;一个前端,一个后端 后端将使用Rails API+Doorkeeper Gem(oauth2提供程序)构建,而前端将使用React Native构建 目前,我使用的是“客户端凭据授权流”,目前运行良好。但是在研究了一段时间之后,这个流不应该用在仅客户端的应用程序中,因为如果有人对应用程序进行反编译,它会暴露Oauth 我们真的需要客户端密钥来获取PKCE流上的访问令牌吗?,oauth,oauth-2.0,rails-api,doorkeeper,pkce,Oauth,Oauth 2.0,Rails Api,Doorkeeper,Pkce,我正在构建2个应用程序;一个前端,一个后端 后端将使用Rails API+Doorkeeper Gem(oauth2提供程序)构建,而前端将使用React Native构建 目前,我使用的是“客户端凭据授权流”,目前运行良好。但是在研究了一段时间之后,这个流不应该用在仅客户端的应用程序中,因为如果有人对应用程序进行反编译,它会暴露客户端的秘密 我也读过关于“隐式赠款流动”的书,它只需要客户id。但这种流动现在似乎已经过时了 根据这一点: 建议使用“PKCE授权码授权”而不是“隐式授权流”。我可以
客户端的秘密
我也读过关于“隐式赠款流动”的书,它只需要客户id
。但这种流动现在似乎已经过时了
根据这一点:
建议使用“PKCE授权码授权”而不是“隐式授权流”。我可以让它工作,但问题是它仍然需要客户机\u secret
才能获得访问\u令牌
,应该这样吗
以下是我正在进行的样本流:
curl -X POST 'http://localhost:3000/oauth/authorize?client_id=xxxx&redirect_uri=urn:ietf:wg:oauth:2.0:oob&response_type=code&scope=public&code_challenge=testchallenge&code_challenge_method=plain'
这将给我以下答复:
{
"status": "redirect",
"redirect_uri": {
"action": "show",
"code": "8quZ-EAiKKG2EKnQiSYs3xeFRCgsIwcTbaWNdjnpyFg"
}
}
{
"error": "invalid_client",
"error_description": "Client authentication failed due to unknown client, no client authentication included, or unsupported authentication method."
}
然后我将使用上面的代码通过下面的请求获取访问令牌:
curl -i http://localhost:3000/oauth/token \
-F grant_type="authorization_code" \
-F client_id="xxxx" \
-F client_secret="xxxx" \
-F code="8quZ-EAiKKG2EKnQiSYs3xeFRCgsIwcTbaWNdjnpyFg" \
-F redirect_uri="urn:ietf:wg:oauth:2.0:oob" \
-F code_verifier="testchallenge"
现在,问题是,为了将code>交换到access\u令牌
I仍然需要client\u secret
。如果两者都只是公开我的客户机密
,那么它与“客户凭证授权流”有何不同
上述命令将返回以下内容:
{
"access_token": "nQoorBqLxQH4qFpmlx3mGG6Cd_TfX4d3L3gAGOTwrFs",
"token_type": "Bearer",
"expires_in": 7200,
"scope": "public",
"created_at": 1595517643
}
如果我没有在请求中包含客户机密
,则响应如下:
{
"status": "redirect",
"redirect_uri": {
"action": "show",
"code": "8quZ-EAiKKG2EKnQiSYs3xeFRCgsIwcTbaWNdjnpyFg"
}
}
{
"error": "invalid_client",
"error_description": "Client authentication failed due to unknown client, no client authentication included, or unsupported authentication method."
}
下面是我的问题:
我们真的需要client\u secret
才能在PKCE流上获取access\u token
如果“PKCE流”只会暴露客户机的秘密,为什么建议使用它
它与“客户端凭据授予流”有什么不同?后者还公开了客户端\u机密
门卫PKCE文件:
我们真的需要客户端密钥来获取PKCE流上的访问令牌吗
视情况而定。最初引入PKCE是为了保护公共客户机(无法保护机密的客户机)。但最近,通过实践,PKCE成为授权代码授予的建议()
2.1.1。授权代码授予
客户端必须防止将授权代码注入(重播)到
攻击者的授权响应。PKCE[RFC7636]的使用
为此目的,建议采取行动。OpenID Connect“nonce”参数和
也可以使用ID令牌声明[OpenID]。PKCE挑战或
OpenID连接“nonce”必须是特定于事务且安全的
绑定到交易所在的客户端和用户代理
开始
注:尽管迄今为止PKCE被设计为一种保护机制
本机应用程序,此建议适用于所有类型的OAuth客户端,
包括web应用程序
如果“PKCE流”只会暴露客户端的秘密,为什么建议使用它
简而言之,为了避免授权代码重播攻击()。这发生在终端用户的设备中,而不是在数据传输中。对于OAuth 2.0令牌请求,TLS是必需的
它与“客户端凭据授予流”有什么不同,后者也会公开客户端的机密
由于令牌请求是通过TLS完成的,因此没有授权将公开凭据
我认为在你的情况下,客户是一个机密客户()。因此,我建议在授权服务器中检查这一方面。我正在Rails控制台中创建一个类似这样的Doorkeeper::应用程序
:
Doorkeeper::Application.create :name => 'Test App', :uid => 'xxxx', :secret => 'xxxx', :redirect_uri => 'urn:ietf:wg:oauth:2.0:oob'
似乎我需要将Doorkeeper::Application
的机密字段设置为false
,以便能够在不使用客户机密的情况下获取访问令牌
因此,上述代码将变为:
Doorkeeper::Application.create :name => 'Test App', :uid => 'xxxx', :secret => 'xxxx', :redirect_uri => 'urn:ietf:wg:oauth:2.0:oob', :confidential => false
我在以下方面找到了解决方案:
PKCE授权码流是为客户端无法安全保护机密的设置而发明的。因此,在PKCE中使用授权码流时,您不需要密码,或者更准确地说,客户端密码没有任何意义
似乎您正在经历的是一个看门人bug(请参阅)。所以我担心,在他们修复之前,你必须使用一些虚假的客户秘密
但只要Doorkeeper正确地实现了PKCE流的其余部分,这就不应该成为问题,因为此流不依赖于任何静态客户端机密,而是使用动态创建的代码验证器,正如您已经指出的那样
我不确定我是否正确理解您正在使用的处理登录的客户端类型。如果是SPA或移动应用程序,您应该使用PKCE的授权码流,但如果您正在实施一个“经典”web应用程序,其中登录在某个后端服务中处理,您应该使用正常的授权码流,使用客户端密码,因为后端可以信任以保护密码
顺便说一句,我刚刚检查了我正在进行的一个项目中的代码,我在其中构建了一些Angular SPA,它通过Auth0作为身份提供者进行身份验证。我在PKCE中使用授权代码流,我绝对不会向Auth0发送任何客户机机密,因为很明显,该流是按预期实现的。所以这真的是看门人的问题
还有一件事:我不知道您提供的请求是否只是示例,但我宁愿使用安全方法,如S256,而不是您在问题中引用的RFC中推荐的方法。PKCE不需要客户端secret@Evert做这意味着看门人出了问题?当使用access\u token
交换code
时,必须存在client\u secret
。我的理解是,这对于此流程的意图没有多大意义<代码>客户端