OAuth 2.0授权代码授权无保密

时间:2016-09-02 10:02:56

标签: azure oauth adal

因此,我一直在考虑使用Microsoft AD为使用Azure AD的自定义API使用Microsofts cordova-plugin-ms-adal plugin(使用本机库)为Cordova移动应用设置OAuth 2.0。这一切都运作良好,但我对秘密的使用(或更具体地说,它的缺席)有点困惑。

在网络上的许多文章中,他们声明当使用授权代码授予和请求令牌时,您将包含该秘密。并且当您可以安全地存储密钥时,此授权类型非常适合使用。在服务器上。

然而,插件并不要求在应用程序中指定密码(并且正确地如此),但它仍然使用授权代码授权进行身份验证。我也可以手动拨打

https://login.windows.net/common/oauth2/authorize?resource=http://***.onmicrosoft.com/***API&client_id=***&response_type=code&redirect_uri=http://***.onmicrosoft.com/***App

在我的浏览器中,登录,获取代码,然后使用

POST到https://login.windows.net/common/oauth2/token
grant_type: authorization_code
client_id: ***
code: ***
redirect_uri: http://***.onmicrosoft.com/***App
resource: http://***.onmicrosoft.com/***API

它有效,所以我得到了一个有效的JWT,而不必发送秘密

为什么!?这不太安全吗? (我也注意到OAuth 2.0 spec section 4.1.3没有声明授权类型授权码需要秘密!?)

在没有秘密/基本身份验证标头的情况下使用授权类型的authorization_code会有什么影响?

3 个答案:

答案 0 :(得分:4)

使用授权代码授权与所谓的机密客户端(具有客户端密钥的客户端)比使用公共客户端更安全。

这是因为授权代码本身的交换在前端通道中作为URL参数发生,即通过浏览器,因此相对容易受到跨脚本,点击,网络/ DNS操作等攻击。意味着专用攻击者可能在某些情况下窃取用户的授权代码(草率用户,攻击者网络控制,服务器实现中的草率重定向URI匹配等)。

要交换访问令牌的授权代码,机密客户端必须在授权代码旁边的HTTPs保护呼叫上显示客户端机密,而公共客户端没有任何方法可以确保它确实是指定的客户。

这意味着攻击者可以轻而易举地模仿公共客户端,因为这只需要非秘密信息(他可以抓住client_idredirect_uri来自他自己的浏览器)以及他可以通过上述攻击获得的授权code

虽然抓住机密客户端的授权代码以相同的方式工作,但攻击者无法使用它并将其交换为访问令牌,因为为了这样做,他需要一个客户端秘密,这通常更难获得攻击者。秘密通常存储在后端存储中的服务器上,并且只通过安全的HTTPs通道进行通信,因此它不会泄漏。

答案 1 :(得分:3)

grant_type=authorization_code(或任何其他流程)与公共客户端(没有任何秘密或以任何其他方式进行身份验证的客户端)一起使用的含义是授予的访问令牌不代表授权客户端到资源,它只代表用户对资源的授权。

这就是为什么您在Azure AD中会注意到,当您注册本机客户端应用程序(公共客户端)时,您只能将其配置为具有对资源的委派权限,而不是仅限应用程序的权限。

答案 2 :(得分:1)

在您发布的链接中,请求还包括(可能您没有注意到):

Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW

因此client_secret并非真的有必要。

从规范来看,似乎由服务器来决定客户端如何进行身份验证(如果需要):

If the client type is confidential or the client was issued client
credentials (or assigned other authentication requirements), the
client MUST authenticate with the authorization server as described
in Section 3.2.1.