lepture / authlib

The ultimate Python library in building OAuth, OpenID Connect clients and servers. JWS,JWE,JWK,JWA,JWT included.
https://authlib.org/
BSD 3-Clause "New" or "Revised" License
4.49k stars 448 forks source link

`issue_token` endpoint supports only POST type #550

Closed AlexanderPershin closed 1 year ago

AlexanderPershin commented 1 year ago

Describe the bug

token = server.create_token_response()

works only with POST method and formData

Error Stacks

    {
        'headers':  Headers([('Content-Type', 'application/json'), ('Cache-Control', 'no-store'), ('Pragma', 'no-cache'), ('Content-Length', '35')]),
        '_status_code': 400, 
        '_status': '400 BAD REQUEST',       
        'direct_passthrough': False, '_on_close': [], 'response': [b'{"error": "unsupported_grant_type"}']
     }

To Reproduce

@app.route("/token", methods=["GET"])
def access_token():
        token = server.create_token_response()

        return token

Expected behavior

When using GET method on /token endpoint server.create_token_response() will accept request search params instead of form data request body and continue authentication flow

Environment:

Additional context

Add any other context about the problem here.

AlexanderPershin commented 1 year ago

For now in order to surpass this I had to add os.environ['AUTHLIB_INSECURE_TRANSPORT'] = 'true' and create POST request using GET request object:

    new_request = Request.from_values(method='POST', input_stream=StringIO(
        data), content_length=len(data), content_type="multipart/form-data")

    new_request.form = get_request.args

and then pass it to server

        req = get_to_post(request, app)

        token = server.create_token_response(request=req)
lepture commented 1 year ago

@AlexanderPershin per RFC, issuing token endpoint can only support POST method with form data. It is a standard.

I'll close this ticket now, you can reopen it if you find a RFC that telling people can use GET for issuing a token.

AlexanderPershin commented 1 year ago

Okay, got it. I just need to migrate the existing project from Flask-OAuthlib to Authlib and connect the frontends that use the GET method to get the access_token to the API. I suppose I would then have to update the frontends, although that would take a lot of work. Thanks for your reply anyway

lepture commented 1 year ago

Why is your project fetching token from front end? It seems unsafe for me.

AlexanderPershin commented 1 year ago

It does not directly uses GET request it's just uses redirects. And /token endpoint particularly uses GET method so I can't get around that. The code was written several years ago by other developer and now I need to refactor it