本文介绍了Microsoft 身份平台和 OAuth 2.0 授权代码流错误 400 Bad Request的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

现在我收到了400 错误请求";代码流认证第二步的响应,当我发回用户登录token端点后收到的authorization_code时,请求access_token.

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

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

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

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

https://login.microsoftonline.com/common/oauth2/v2.0/token代码=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)如果 response.StatusCode = System.Net.HttpStatusCode.OK 那么使用阅读器作为 StreamReader = New StreamReader(response.GetResponseStream())返回 reader.ReadToEnd()结束使用万一结束使用

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

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

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

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

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

{错误":无效请求",error_description":AADSTS900144:请求正文必须包含以下参数:grant_type".\r\n跟踪 ID:6a487d0d-3d7f-4d8b-896f-7df8453ebd00\r\nCorrelation ID:34dc8d-c8d-e-b086b77890fb\r\n时间戳:2021-01-02 18:51:43Z",错误代码":[900144],时间戳":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() 在返回 http 状态代码 400(错误请求)时引发异常

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

I need a bit of help understanding which is the problem with Microsoft Identity Platform login on my cms (ASP.NET Webforms). It used to work without problems, last time I tried was maybe a month ago.

Now I'm receiving a "400 bad request" response on the second step of the code flow authentication, when I send back the authorization_code that I received after the user login to the token endpoint, to request the access_token.

The original GET request to send the user to the Microsoft login panel is (I split it for readibility):

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

It works and microsoft redirects the user to the callback url specified in app registration and in the request (local developement machine).

Then my POST request to receive the access_token, when I receive the error response, but used to work up to at least 1 month ago, is this:

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

Parameters are encoded and sent that way:

I double checked the parameters with the official docs. I'm passing them as a POST request (application/x-www-form-urlencoded) with:

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

Any hint on why this that used to work now gives back bad request? I tryed to check docs for changes but nothing changed apart:

But my app has been registered before that date, also I'm just asking for the openID (I just need Microsoft id for that user that I have linked in my local db), also I can actaully loginn and receive back the autrhorization code in the first step of the flow.

Any help is greatly appreciated. Thank you so much

EDIT: I tested the second request in postman too and I receive this error, but the grant_type param is there of course:

{
"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"

}

In post man you can send the parameters both as form-data or x-www-form-urlencoded. I tried both with no luck. Funny thing same happens using the microsoft "demo" links in the doc. They provide the direct link to postman, you just have to change the code that you receiver from the first link, but I get the same identical error complaining no grant_type param is specified in the post.

解决方案

Ok I found the issue. I will leave all my process in the question in case any other use will have a similar issue.

The first problem was the library used to make the request:

 System.Net.HttpWebResponse

This "very smart" library,has the nice habit of throwing an exception when it doesn't receiver a 200 status code back...What put me on the right track was this post: .Net HttpWebRequest.GetResponse() raises exception when http status code 400 (bad request) is returned

Thanks to that user on Stack Overflow I've been able to read the real response error which was that in my redirect url I forgot to add a trailing / at the end. So I added a second URL in the Azure portal as a callback url. Now I have both /login and /login/ as callback destination urls.Since in my app I retrieve this url dynamically, maybe I changed some function in the meanwhile that sent back the url without / at the end... that's why it was not working as before.

这篇关于Microsoft 身份平台和 OAuth 2.0 授权代码流错误 400 Bad Request的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-12 23:01