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

Issue

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

enter image description here

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:

enter image description here

Solution

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

Answered By – chingis

Answer Checked By – Marie Seifert (GoLangFix Admin)

Leave a Reply

Your email address will not be published.