Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OAuth2 Authorization Code flow fails #550

Closed
jonathanunderwood opened this issue Sep 19, 2019 · 12 comments
Closed

OAuth2 Authorization Code flow fails #550

jonathanunderwood opened this issue Sep 19, 2019 · 12 comments

Comments

@jonathanunderwood
Copy link
Contributor

Describe the bug

I believe the following code should implement the OAuth2 Authorization Code flow for the openapi/swagger docs interface:

from fastapi import FastAPI, Depends
from fastapi.openapi.models import OAuthFlows as OAuthFlowsModel
from fastapi.security import OAuth2


CLIENT_ID = "MYVERYSECRETID"
CLIENT_SECRET = "MYVERYSSECRETSECRET"
API_BASE_URL = "https://my.oauth2.server.com"
AUTHORIZE_URL = f"{API_BASE_URL}/as/authorization.oauth2"
ACCESS_TOKEN_URL = f"{API_BASE_URL}/as/token.oauth2"
SCOPES = {"profile": "profile", "openid": "openid"}


app = FastAPI()  # pylint: disable=invalid-name


auth_code_flow = OAuthFlowsModel(
    authorizationCode={
        "tokenUrl": ACCESS_TOKEN_URL,
        "authorizationUrl": AUTHORIZE_URL,
        "scopes": SCOPES,
    }
)

oauth2_scheme = OAuth2(flows=auth_code_flow)


@app.post("/test")
async def login_for_access_token(token: str = Depends(oauth2_scheme)):
    print("in /test")

This successfully produces an Authorization button in the /docs swagger UI, which when used successfuly takes the user to the authorization service to enter credentials.

The next part of the process, exchanging the authorization code for a token, which should happen server side not client side, fails. In the UI I see Auth ErrorTypeError: Failed to fetch. Looking at the network traffic I see that the client is trying to connect to the TOKEN_URL, and (obviously) failing. My understanding is that this is not how Authorization Code Flow is supposed to work - the authorization code should be passed from the client to the API server, and the API server should take care of exchanging the code for a token by going to the token URL.

In the console where I am running the fastAPI application I see:

INFO: ('127.0.0.1', 56658) - "GET /docs HTTP/1.1" 200
INFO: ('127.0.0.1', 56658) - "GET /openapi.json HTTP/1.1" 200
INFO: ('127.0.0.1', 56665) - "GET /docs/oauth2-redirect?code=y2Kw0z-EYXXXX2jAAAAAw&state=VGh1IFNlcCAxOSAyMDE5IDEwOjMyOjUXXXXNVCswMTAwIChCcml0aXNoIFN1bW1lciBUaW1lKQ%3D%3D HTTP/1.1" 200

(Have X'ed out some characters)

This is the problem I referred to in #335

To Reproduce
Steps to reproduce the behavior:

  1. See above.

Expected behavior
I would expect to see successful authentication.

Screenshots

Environment:
fastapi 0.38.1

  • Python version, get it with:
    Python 3.7.4
@jonathanunderwood jonathanunderwood added the bug Something isn't working label Sep 19, 2019
@dmontagu
Copy link
Collaborator

dmontagu commented Sep 19, 2019

Based on reading these docs it seems like it is behaving correctly:

  1. Auth0's SDK sends this code to the Auth0 Authorization Server (/oauth/token endpoint) along with the application's Client ID and Client Secret.

My interpretation is that the "Auth0 SDK" is basically equivalent to your client, and so it sounds to me like they are saying the client should be the thing sending the code to the /token endpoint. (For reference, the "Auth0 Tenant" is basically equivalent to your auth server.)

Re-reading the docs, I'm not sure if the above interpretation is right any more.

@jonathanunderwood
Copy link
Contributor Author

I think the above interpretation might be wrong.

Yup - in that picture, the "Regular web app" is both the client and the API server. It's a really confusing picture that had me scratching my head for a couple of hours a few weeks back. Glad to see I'm not the only one that finds it a bit confusing.

@dmontagu
Copy link
Collaborator

For what it's worth, the swagger docs client logic is handled entirely outside of FastAPI (FastAPI just includes a reference to a cdn-hosted script); I think this repo might be a better place to look for information (or post an issue).

@jonathanunderwood
Copy link
Contributor Author

It looks like this is not implemented upstream in swagger-ui:

swagger-api/swagger-ui#5348

@jonathanunderwood
Copy link
Contributor Author

Also relevant:

swagger-api/swagger-ui#4969

@chbndrhnns
Copy link

I am also facing this error message Auth ErrorTypeError: Failed to fetch in swagger ui. While I understand this needs to be implemented there first, it might be a good idea to inform the user
somehow that this functionality is not working at the moment.

@kuwv
Copy link
Contributor

kuwv commented Dec 27, 2019

Probably not a bug. I have been using playing with it since August. Already submitted a pull request: #797

@jmereaux
Copy link

jmereaux commented Apr 1, 2021

Also seeing this same error message Auth ErrorTypeError: Failed to fetch in the swagger UI when performing the OAuth Authorization Code flow.

Seems like it is caused by a CORS error under the hood :

Access to fetch at 'https://eu-de.appid.cloud.ibm.com/oauth/v4/xxxxxxxx-c69f-4565-89af-xxxxxxxxxxxx/token' from origin 'http://localhost:8000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

Is this simply not supported or has the situation evolved ?
Any way to make the OAuth2 Authorization Code flows work with the FastAPI Swagger UI ?

@JohnnySimple
Copy link

I'm having a similar issue. I get Auth Error Error: Not Found when I submit username and password using OAuth2PasswordRequestForm.

@pozsa
Copy link

pozsa commented Nov 29, 2021

Also seeing this same error message Auth ErrorTypeError: Failed to fetch in the swagger UI when performing the OAuth Authorization Code flow.

Seems like it is caused by a CORS error under the hood :

Access to fetch at 'https://eu-de.appid.cloud.ibm.com/oauth/v4/xxxxxxxx-c69f-4565-89af-xxxxxxxxxxxx/token' from origin 'http://localhost:8000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

Is this simply not supported or has the situation evolved ? Any way to make the OAuth2 Authorization Code flows work with the FastAPI Swagger UI ?

Sounds like you need to configure CORS on the authorization server.
Keycloak example:
image

@gregorybchris
Copy link

To fix Auth Error Error: Not Found I had to ensure that the login endpoint was named /token. Naming the endpoint /login or something similar will not work as the Swagger UI looks specifically for /token.

@asionesjia
Copy link

asionesjia commented Oct 16, 2022

Sorry, this is the machine translated version. I have successfully solved this problem in my program. The main reason for this problem is that the address pointed to by the Swagger authorization button is not the same as your login api address. Just change the tokenUrl to the correct path. If not, it may not be the same as your problem.
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/users/login")

image

@tiangolo tiangolo added question Question or problem reviewed and removed bug Something isn't working labels Feb 24, 2023
@tiangolo tiangolo changed the title [BUG] OAuth2 Authorization Code flow fails OAuth2 Authorization Code flow fails Feb 24, 2023
Repository owner locked and limited conversation to collaborators Feb 28, 2023
@tiangolo tiangolo converted this issue into discussion #9144 Feb 28, 2023

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Projects
None yet
Development

No branches or pull requests

10 participants