Microsoft 身份平台和 OAuth 2.0 授权代码流错误 400 Bad Request

问题描述

我需要一些帮助来了解我的 cms (ASP.NET Webforms) 上 Microsoft Identity Platform 登录的问题。它曾经可以正常工作,我上次尝试可能是一个月前。

现在我在代码流身份验证的第二步收到“400 bad request”响应,当我发回用户登录令牌端点后收到的authorization_code以请求access_token时。

>

用户发送到 Microsoft 登录面板的原始 GET 请求是(为了便于阅读,我将其拆分):

https://login.microsoftonline.com/common/oauth2/v2.0/authorize
?client_id=myclientappid-xxxx-xxxx-xxxx-xxxxxxxxxxxx
&response_type=code
&redirect_uri=https%3a%2f%2feva3.com%2flogin
&scope=openid
&state=mycustomencodedappinfos
&response_mode=query

它起作用了,微软将用户重定向到应用注册和请求(本地开发机器)中指定的回调 url。

然后我的 POST 请求接收 access_token,当我收到错误响应时,但用于工作至少 1 个月前,是这样的:

https://login.microsoftonline.com/common/oauth2/v2.0/token
code=M.R2_BAY.21818906-b374-00e0-xxxxx-xxxxxxxxxxxx
&scope=openid
&client_id=myclientappid-xxxx-xxxx-xxxx-xxxxxxxxxxxx
&client_secret=myclientSecretxxxxxxxxxxxx
&redirect_uri=https://eva3.com/login
&grant_type=authorization_code

参数以这种方式编码和发送:

我用官方文档仔细检查了参数。我将它们作为 POST 请求(application/x-www-form-urlencoded)传递给:

Using response As System.Net.HttpWebResponse = CType(request.GetResponse(),System.Net.HttpWebResponse)
If response.StatusCode = System.Net.HttpStatusCode.OK Then
    Using reader As StreamReader = New StreamReader(response.GetResponseStream())
        Return reader.ReadToEnd()
    End Using
End If
End Using

是否有任何提示,为什么以前可以使用的方法现在会返回错误的请求?我试图检查文档是否有变化,但没有任何变化:

从 2020 年 11 月开始,没有经过验证的发布者,最终用户将无法再对大多数新注册的多租户应用授予同意。这将适用于 2020 年 11 月 8 日之后注册的应用程序,使用 OAuth2.0 请求基本登录和读取用户配置文件以外的权限,并请求与应用程序注册所在租户不同的租户的用户同意。警告将显示在同意屏幕上,告知用户这些应用存在风险并且来自未经验证的发布商。

但是我的应用程序已经在那个日期之前注册了,而且我只是要求 openID(我只需要我在本地数据库链接的那个用户的 Microsoft id),我也可以实际登录并接收回流程第一步中的授权代码

非常感谢任何帮助。非常感谢

编辑:我也在邮递员中测试了第二个请求,但收到此错误,但grant_type 参数当然在那里:

{
"error": "invalid_request","error_description": "AADSTS900144: The request body must contain the following parameter: 'grant_type'.\r\nTrace ID: 6a487d0d-3d7f-4d8b-896f-7df8453ebd00\r\nCorrelation ID: 16efbdc3-4c3d-4e0d-8835-b086b77890fb\r\nTimestamp: 2021-01-02 18:51:43Z","error_codes": [
    900144
],"timestamp": "2021-01-02 18:51:43Z","trace_id": "6a487d0d-3d7f-4d8b-896f-7df8453ebd00","correlation_id": "16efbdc3-4c3d-4e0d-8835-b086b77890fb","error_uri": "https://login.microsoftonline.com/error?code=900144"

}

在邮递员中,您可以将参数作为表单数据或 x-www-form-urlencoded 发送。我都试过了,但都没有运气。使用文档中的微软“演示”链接也会发生同样有趣的事情。他们提供了到邮递员的直接链接,您只需更改从第一个链接接收的代码,但我收到相同的错误,抱怨帖子中没有指定 grant_type 参数。

解决方法

好的,我发现了问题。我会将我的所有过程留在问题中,以防任何其他用途出现类似问题。

第一个问题是用于发出请求的库:

 System.Net.HttpWebResponse

这个“非常聪明”的库,有一个很好的习惯,当它没有接收到 200 状态码时抛出一个异常...... 这篇文章让我走上了正轨:.Net HttpWebRequest.GetResponse() raises exception when http status code 400 (bad request) is returned

感谢 Stack Overflow 上的那个用户,我已经能够读取真正的响应错误,即在我的重定向 url 中我忘记在末尾添加尾随 /。所以我在 Azure 门户中添加了第二个 URL 作为回调 URL。现在我有 /login 和 /login/ 作为回调目标网址。 因为在我的应用程序中我动态地检索了这个 url,也许我同时更改了一些函数,在最后发送回没有 / 的 url ......这就是它不像以前那样工作的原因。