因此,我一直在考虑使用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/tokengrant_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会有什么影响?
答案 0 :(得分:4)
使用授权代码授权与所谓的机密客户端(具有客户端密钥的客户端)比使用公共客户端更安全。
这是因为授权代码本身的交换在前端通道中作为URL参数发生,即通过浏览器,因此相对容易受到跨脚本,点击,网络/ DNS操作等攻击。意味着专用攻击者可能在某些情况下窃取用户的授权代码(草率用户,攻击者网络控制,服务器实现中的草率重定向URI匹配等)。
要交换访问令牌的授权代码,机密客户端必须在授权代码旁边的HTTPs保护呼叫上显示客户端机密,而公共客户端没有任何方法可以确保它确实是指定的客户。
这意味着攻击者可以轻而易举地模仿公共客户端,因为这只需要非秘密信息(他可以抓住client_id
和redirect_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.