我有一个问题不知道如何解决。
我想使用 OAuth2 和 Microsoft 的授权服务器来获取具有用户一组权限的访问令牌,该令牌可用于通过 Microsoft Graph 从 OneDrive 应用程序检索信息
我陷入了从授权服务器获取
code
的阶段,然后应该执行对 secured
ASP.NET 后端端点的调用。通过简单的按钮,我code
Microsoft OAuth 端点 (
GET
) 以及我的login.microsoftonline.com/common/oauth2/v2.0/authorize
securedASP.NET 端点。
redirect_uri
是response_type
,code id_token
是respones_mode
。在所有 OAuth 舞蹈之后,我收到来自 Microsoft 域(来源为
form_post
)的 POST
呼叫,其中包含 login.live.com
、id_token
和 code
。该调用针对之前在 state
中指定的后端端点。重点是我有一个活动会话(用户已登录),并且我需要浏览器在请求中包含 redirect_uri
cookie。在本例中,Cookie 的
ASP.NET_SessionId
属性设置为 SameSite
。如果我将 Lax
cookie 属性设置为
SameSite
,则可以到达端点。否则,浏览器会阻止潜在的 CSRF 攻击,并且不包含令牌,只能访问具有 None
属性的端点,这在我的场景中是不可接受的。让我想到的是最后一次调用的 [AllowAnonymous]
是
Initiator
,对于其他使用 OAuth2 的网站来说通常是 oauth20_authorize.srf
。我不确定这是否是正确的道路。提前谢谢大家,希望有人知道发生了什么,或者可能有一个安全的解决方案。
document
。响应模式使用
POST方法重定向用户,因此对于
response_mode = form_post
属性它无法工作。浏览器不会附加 cookie,因为浏览器就是这样工作的。Mozilla 文档指出:
使用 Strict,浏览器仅发送带有来自 cookie 源站点的请求的 cookie。
Lax 类似,只是当用户导航到 cookie 的原始站点时浏览器也会发送 cookie(即使用户来自不同的站点)。如果将
SameSite=Lax
设置为
SameSite
,则 None
响应方法将起作用。当然,由于安全漏洞(CRFS 攻击),这个解决方案远非完美。我决定将form_post
更改为
response_mode
,拒绝POST方法并使用GET代替。谈到安全性,最好还是使用 POST,但我还没有找到其他方法。该解决方案的缺点是,用于交换令牌的代码将存储在日志、浏览器等中。为了使其更安全,我实施了 PKCE(代码证明密钥)并将 query
有效性设置为 60 秒。我在使用 MSAL.js npm 包时遇到了完全相同的问题。我不想退回到
code
(或在 MSAL 的情况下为
query
)作为响应模式或更改 SessionID cookie 的 fragment
值。我发现的解决方法是,在 SameSite
上,当从 Microsoft 收到帖子时,构建一个简单的 html
redirect_uri
,其中每个表单变量都有隐藏输入,然后使用一些 javascript 来重新发布表单当页面加载时,还有一个额外的变量只是为了指定它已“重新提交”(或者您可能会发布到您网站上的另一个 URL - 这就是我所做的)。如果你这样做,SessionID cookie应该包含在第二篇文章中,并且你的会话应该可以工作(在我的例子中,我有一个我想验证的CSRF令牌)。
构建表单的代码确保表单输入的键和值被转义,并且我添加了一些清理正则表达式来删除任何不匹配的内容
<form>
。我还有
/[^a-zA-Z0-9\-._=]/g
标头,它会阻止表单在加载时提交,我用随机数解决了这个问题。这里是生成重新提交表单 HTML 的 TypeScript 代码(我使用的是 Express):
Content-Security-Policy