lorawan-stack icon indicating copy to clipboard operation
lorawan-stack copied to clipboard

Can't exchange authorization code for an OAuth access token

Open romach opened this issue 2 years ago • 4 comments

Summary

I get 400 error when I try to exchange authorization code for an OAuth access token according to the documentation https://www.thethingsindustries.com/docs/reference/api/authentication/

Response body:

{
    "code": 3,
    "message": "error:pkg/oauth:invalid_request (invalid or missing request parameter)",
    "details": [
        {
            "@type": "type.googleapis.com/ttn.lorawan.v3.ErrorDetails",
            "namespace": "pkg/oauth",
            "name": "invalid_request",
            "message_format": "invalid or missing request parameter",
            "correlation_id": "f58fe39f7984450a969c2134bac2835c",
            "code": 3
        }
    ]
}

Steps to Reproduce

  1. Get authorization code with request https://eu1.cloud.thethings.network/oauth/authorize?client_id=<oauth_client_id>&redirect_uri=<redirect_uri>&response_type=code
  2. Exchange authorization code for an OAuth access token using request
POST /oauth/token HTTP/1.1
Host: eu1.cloud.thethings.network
Content-Type: application/json
Authorization: Basic <AUTHORIZATION_HEADER>
Content-Length: 156

{
    "grant_type": "authorization_code",
    "code": "<AUTHORIZATION_CODE>"
}

Current Result

Error with code 400 and body:

{
    "code": 3,
    "message": "error:pkg/oauth:invalid_request (invalid or missing request parameter)",
    "details": [
        {
            "@type": "type.googleapis.com/ttn.lorawan.v3.ErrorDetails",
            "namespace": "pkg/oauth",
            "name": "invalid_request",
            "message_format": "invalid or missing request parameter",
            "correlation_id": "f58fe39f7984450a969c2134bac2835c",
            "code": 3
        }
    ]
}

Expected Result

Response with status code 200 and body

{
  "access_token": "XXXXX", 
  "token_type": "bearer", 
  "expires_in": "3600",
  "refresh_token": "YYYYY"
}

Relevant Logs

No response

URL

https://eu1.cloud.thethings.network/oauth/token

Deployment

The Things Stack Community Edition

The Things Stack Version

No response

Client Name and Version

No response

Other Information

No response

Proposed Fix

No response

Contributing

  • [ ] I can help by doing more research.
  • [ ] I can help by implementing a fix after the proposal above is approved.
  • [X] I can help by testing the fix before it's released.

Code of Conduct

romach avatar Sep 05 '23 20:09 romach

The general request looks ok. And you're using standard basic auth credentials base64 encoded "client-id:client-password"?

KrishnaIyer avatar Sep 13 '23 09:09 KrishnaIyer

The general request looks ok. And you're using standard basic auth credentials base64 encoded "client-id:client-password"?

Yes I do.

The issue is that error message invalid or missing request parameter is to vague. So I can't determine the reason for error.

romach avatar Sep 13 '23 11:09 romach

The Authorization Code is exactly 98 characters. So adding that to the request, the content length without whitespaces is 143 characters.

{"code":"MF2XI.JQ4KK77YEP4HAA3RHO2PJMK3F4JS4L37NDVEUMY.U4662YGK27JU4UXDQBJOXZ7NFK2GDP4TWK7UCQEB536ZBZAZXM3A","grant_type":"authorization_code"}

I see that the content length of your request is 156. Where do these extra characters come from? Are they simply whitespaces?

@adriansmares: Since the above Token request is explicitly POST, I see the E_INVALID_REQUEST (the OSIN error for this invalid_request) only if the parsing of the form failed. But we explicit set the form values before calling this function. Do you see something?

KrishnaIyer avatar Sep 14 '23 07:09 KrishnaIyer

The problem here is that the redirect URI is not provided during the token exchange. The OAuth client which is affected here has multiple redirect URIs, and the first redirect URI in the OAuth client is probably different from the one requested during authorization.

Providing the redirect_uri explicitly in the body of the token exchange request should fix this issue. The redirect_uri is supposed to be provided by the caller explicitly during the token exchange, but for convenience osin will use the first redirect URI in case none is provided. It will still validate the redirect URI against the one provided in the authorization request, and since probably the implicit redirect URI is not matching that one, the error occurs.

This is mainly from the backend logs of the Identity Server. We don't propagate error causes from osin, but maybe in the future we can take a look if we should do it.

adriansmares avatar Sep 14 '23 08:09 adriansmares