通过golang.org/x/oauth2获取Microsoft oauth2令牌时出现随机错误。

huangapple go评论119阅读模式
英文:

Random errors acquiring Microsoft oauth2 token via golang.org/x/oauth2

问题

我使用标准的Go库golang.org/x/oauth2来从Microsoft用户那里获取OAuth2令牌。

这是我使用的oauth2配置:

return oauth2.Config{
	ClientID:     clientID,
	ClientSecret: clientSecret,
	Endpoint:     microsoft.AzureADEndpoint("common"),
	Scopes: []string{
		"https://graph.microsoft.com/.default",
	},
}

这是我获取重定向URL的方式:

oauth2Config.AuthCodeURL(state, oauth2.ApprovalForce, oauth2.AccessTypeOffline)

这是我将在oauth2回调中获取的代码交换为oauth2令牌的方式:

oauth2Config.Exchange(ctx, code)

我在与GitHub、Google Cloud Platform、Bitbucket和DigitalOcean集成时使用相同的代码。它对我来说一直工作得很好,并且与Microsoft一起使用也有效,但有时我会随机遇到以下错误之一:

AADSTS90013 用户输入无效

或者

AADSTS900144:请求正文必须包含以下参数:'grant_type'。

我不明白可能的原因是什么。第一个错误可能是由于Microsoft同意屏幕中的一些JS错误引起的。第二个错误没有意义- oauth2库正确设置了grant_type值,我搜索了这个错误,它说问题可能在于不正确的编码,应该是x-www-form-urlencoded,但我查看了oauth2库并确认它确实是这样做的。

或者可能存在在同一用户下重复获取令牌的超时时间。

更新:我在代码交换为令牌的过程中遇到了这些错误。

更新2:我开始随机地在与其他提供商(如DigitalOcean)进行代码到令牌交换时遇到oauth2错误。错误也发生在代码到令牌交换过程中。类似于以下错误:

ERROR STACKTRACE: oauth2: cannot fetch token: 400 Bad Request
Response: {"error":"bad_request","error_description":"invalid semicolon separator in query"}{"error":"invalid_request","error_description":"The request is missing a required parameter, includes an unsupported parameter value, or is otherwise malformed."}
could not get auth token

我查看了我的oauth2配置中的值,都是正确的,但是这些值没有进行URL编码(我认为oauth2库会处理这个问题)。

我最近将我的Go升级到了1.17.6版本。

更新3:我注意到我的DigitalOcean和Microsoft的oauth2配置都没有指定AuthStyle,所以我手动将其设置为oauth2.AuthStyleInParams。但是这仍然没有解决问题。在与DigitalOcean的几次重复尝试之后,它开始随机返回以下错误:

Response: {"error":"bad_request","error_description":"invalid semicolon separator in query"}{"error":"invalid_request","error_description":"The request is missing a required parameter, includes an unsupported parameter value, or is otherwise malformed."}

我甚至认为这不是一个有效的错误,请求URL和正文中都没有分号符号。

更新4:听起来可能很愚蠢,但当我重新启动我的应用程序(我通过GoLand运行和调试它)时,DigitalOcean的oauth正常工作,直到我通过oauth2连接了一个Microsoft帐户(这也正常工作),但是如果我再次连接(重新连接)DigitalOcean帐户,它就停止工作了 ¯_(ツ)_/¯

更新5:下面是oauth2库中doTokenRoundTrip函数的调试监视。令牌交换请求返回400 Bad Request

通过golang.org/x/oauth2获取Microsoft oauth2令牌时出现随机错误。

请求正文:

client_id=[已删除]&client_secret=[已删除]&code=e50e6dc91ec6b855becdef7a32cc4e28684851ccf385b2f6bb667ed6ec1172df&grant_type=authorization_code&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fv1%2Fdigitalocean%2Foauth2%2Fcallback

URL和正文看起来都没问题。然而,这返回了以下错误:

Response: {"error":"bad_request","error_description":"invalid URL escape "%\x9b\x06""}{"error":"invalid_request","error_description":"The request is missing a required parameter, includes an unsupported parameter value, or is otherwise malformed."}

更新6:交换请求头:

通过golang.org/x/oauth2获取Microsoft oauth2令牌时出现随机错误。

英文:

I use the standard go library golang.org/x/oauth2 to acquire an OAuth2 token from Microsoft users.

This is the oauth2 config I use:

return oauth2.Config{
	ClientID:     clientID,
	ClientSecret: clientSecret,
	Endpoint:     microsoft.AzureADEndpoint("common"),
	Scopes: []string{
		"https://graph.microsoft.com/.default",
	},
}

This is how I get the redirect URL:

oauth2Config.AuthCodeURL(state, oauth2.ApprovalForce, oauth2.AccessTypeOffline)

And this is how I exchange the code acquired in my oauth2 callback to the oauth2 token:

oauth2Config.Exchange(ctx, code)

I use the same code for integrating with github, google cloud platform, bitbucket and digitalocean. It has been working fine for me and it does work with Microsoft but sometimes I randomly get one of the following errors:

> AADSTS90013 Invalid input received from the user

or

> AADSTS900144: The request body must contain the following parameter: 'grant_type'.

And I don't understand what might be the reason. The first error potentially could be caused by some JS bugs in the Microsoft consent screen. The second error makes no sense – oauth2 lib sets grant_type value correctly, I search for this error and it says the issue could be in the incorrect encoding which should be x-www-form-urlencoded but I've looked up oauth2 library and confirmed that's exactly what it does.

Or maybe there's a timeout for a repeated acquisition of a token under the same user.

UPD: I get these errors during the exchange of a code to a token

UPD2: I started to get oauth2 errors randomly with other providers, such as DigitalOcean, the errors also happens during the code to a token exchange. Errors like this:

> ERROR STACKTRACE: oauth2: cannot fetch token: 400 Bad Request
Response: {"error":"bad_request","error_description":"invalid semicolon separator in query"}{"error":"invalid_request","error_description":"The request is missing a required parameter, includes an unsupported parameter value, or is otherwise malformed."}
could not get auth token

I've looked up values in my oauth2 config, it's all correct, the values however are not url encoded (I assume oauth2 lib handles this).

I've recently upgraded my go to 1.17.6

UPD3: I've noticed that my oauth2 configs both for DigitalOcean and Microsoft didn't have AuthStyle specified, so I've set it manually to oauth2.AuthStyleInParams. But this still didn't resolve the issue. After a few repeated attempts with DigitalOcean it started to randomly return the following error:

> Response: {"error":"bad_request","error_description":"invalid semicolon separator in query"}{"error":"invalid_request","error_description":"The request is missing a required parameter, includes an unsupported parameter value, or is otherwise malformed."}

which I don't even think is a valid error, there's no semicolon symbol neither in the request URL nor the body

UPD4. It may sound stupid but when I restart my app (I run-debug it via GoLand) DigitalOcean oauth works just fine until I connect a Microsoft account via oauth2 (which also works fine), but then if I connect (reconnect) DigitalOcean account again then it just stops working ¯_(ツ)_/¯

UPD5. Below is the debug watch of doTokenRoundTrip function inside oauth2 library. The token exchange request returns 400 bad request

通过golang.org/x/oauth2获取Microsoft oauth2令牌时出现随机错误。

The request body:

> client_id=[redacter]&client_secret=[redacted]&code=e50e6dc91ec6b855becdef7a32cc4e28684851ccf385b2f6bb667ed6ec1172df&grant_type=authorization_code&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fv1%2Fdigitalocean%2Foauth2%2Fcallback

The URL and the body both looks good to me. However this returns the following error:

> Response: {"error":"bad_request","error_description":"invalid URL escape "%\x9b\x06""}{"error":"invalid_request","error_description":"The request is missing a required parameter, includes an unsupported parameter value, or is otherwise malformed."}

UPD6. Exchange request headers:

通过golang.org/x/oauth2获取Microsoft oauth2令牌时出现随机错误。

答案1

得分: 1

由于额外的标头引起的问题。通常情况下,只应该有Content-Type: application/x-www-form-urlencoded标头,但如上所示,还有额外的标头,包括Content-Encoding: gzip,这可能导致问题。这些标头是在通过oauth2连接Microsoft帐户后添加的,更具体地说,是因为在获取令牌后我使用了Microsoft Graph SDK(github.com/microsoftgraph/msgraph-sdk-go)。该SDK实现了RoundTripper接口,最终会添加额外的标头。

已将问题提交给graph sdk https://github.com/microsoftgraph/msgraph-sdk-go/issues/91

英文:

The issue caused by the extra headers. Normally it should be only Content-Type: application/x-www-form-urlencoded header but as you can see above there are extra headers including Content-Encoding: gzip which probably causes the issues. These headers added after I connect Microsoft account via oauth2, more specifically is because I use microsoft graph sdk (github.com/microsoftgraph/msgraph-sdk-go) after acquiring the token. This SDK implements RoundTripper interface that eventually adds extra headers.

Submitted the issue to graph sdk https://github.com/microsoftgraph/msgraph-sdk-go/issues/91

答案2

得分: -1

我认为第二个错误是指配置中缺少grant_type

grant_type:authorization_code, 
code: {从授权步骤获取的代码}, 
client_secret: ****

另一种访问OAuth 2.0令牌的方法,请参考此文档

英文:

I think second error refers to the grant_type missing in the config

grant_type:authorization_code, 
code: {code you got from the authorization step}, 
client_secret: ****

Other way of accessing the OAuth 2.0 Token, Please refer this Document

huangapple
  • 本文由 发表于 2022年2月24日 01:37:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/71241676.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定