Search code examples
azureoauth-2.0azure-active-directoryfastapiazure-authentication

fastapi azure auth redirect URI mismatch error


I keep getting below AADSTS50011 error even though I have already specified the correct redirect URI for the relevant app. Can you please provide guidance on resolving this issue? code snippet is attached below. Thank you.

enter image description here enter image description here

from fastapi import FastAPI, Security
from fastapi.middleware.cors import CORSMiddleware
from fastapi_azure_auth import SingleTenantAzureAuthorizationCodeBearer
from pydantic.v1 import BaseSettings
from router.flight_router import flight_router
from router.user_router import user_router

class Settings(BaseSettings):
BACKEND_CORS_ORIGINS = ['http://localhost:8000']
OPENAPI_CLIENT_ID: str = "***"
APP_CLIENT_ID: str = "***"
TENANT_ID: str = "***"
SCOPE_DESCRIPTION: str = "***"

@property
def SCOPES(self) -> dict:
    return {
        'api://**/**': '**',
    }

settings = Settings()

app = FastAPI(
swagger_ui_oauth2_redirect_url='/docs',
swagger_ui_init_oauth={
    'usePkceWithAuthorizationCodeGrant': True,
    'clientId': "***",
},
)

@app.on_event('startup')
async def load_config() -> None:
"""
Load OpenID config on startup.
"""
await azure_scheme.openid_config.load_config()


@app.get("/", dependencies=[Security(azure_scheme)])
async def welcome():
return {"message": "Welcome to Flight Reservation System"}

Solution

  • Thank you for the comment @PGHE.

    I followed this Documentation for creating this project.

    I faced an issue with authorization, so I used the command below to run the project.

     uvicorn main:app --host localhost --port 8000
    

    This helped me get the URL with localhost instead of the following URL: http://127.0.0.1:8000.

    main.py

    import uvicorn
    from fastapi import FastAPI, Security
    from fastapi.middleware.cors import CORSMiddleware
    from fastapi_azure_auth import SingleTenantAzureAuthorizationCodeBearer
    from pydantic import AnyHttpUrl
    from pydantic_settings import BaseSettings
    
    class Settings(BaseSettings):
        BACKEND_CORS_ORIGINS: list[str | AnyHttpUrl] = ['http://localhost:8000']
        OPENAPI_CLIENT_ID: str = "OpenApiIdClientId"
        APP_CLIENT_ID: str = "AppClientId"
        TENANT_ID: str = "TenantId"
        SCOPE_DESCRIPTION: str = "scopeDescription"
          
        @property
        def SCOPE_NAME(self) -> str:
            return f'api://{self.APP_CLIENT_ID}/{self.SCOPE_DESCRIPTION}'  
        @property
        def SCOPES(self) -> dict:
            return {
                self.SCOPE_NAME: self.SCOPE_DESCRIPTION,
            }
       
        @property
        def OPENAPI_AUTHORIZATION_URL(self) -> str:
            return f"https://login.microsoftonline.com/{self.TENANT_ID}/oauth2/v2.0/authorize"
       
        @property
        def OPENAPI_TOKEN_URL(self) -> str:
            return f"https://login.microsoftonline.com/{self.TENANT_ID}/oauth2/v2.0/token"
    
        class Config:
            env_file = '.env'
            env_file_encoding = 'utf-8'
            case_sensitive = True
    settings = Settings()
    app = FastAPI(
        swagger_ui_oauth2_redirect_url='/oauth2-redirect',
        swagger_ui_init_oauth={
            'usePkceWithAuthorizationCodeGrant': True,
            'clientId': settings.OPENAPI_CLIENT_ID,
            'scopes': settings.SCOPE_NAME,
        },
    )
    if settings.BACKEND_CORS_ORIGINS:
        app.add_middleware(
            CORSMiddleware,
            allow_origins=[str(origin) for origin in settings.BACKEND_CORS_ORIGINS],
            allow_credentials=True,
            allow_methods=['*'],
            allow_headers=['*'],
        )
    azure_scheme = SingleTenantAzureAuthorizationCodeBearer(
        app_client_id=settings.APP_CLIENT_ID,
        tenant_id=settings.TENANT_ID,
        scopes=settings.SCOPES,
    )
    @app.on_event('startup')
    async def load_config() -> None:
        """
        Load OpenID config on startup.
        """
        await azure_scheme.openid_config.load_config()
    
    @app.get("/", dependencies=[Security(azure_scheme)])
    async def root():
        return {"message": "Hello World"}
    if __name__ == '__main__':
        uvicorn.run('main:app', reload=True)
    

    I added the following URI in the App Redirect URI as shown below:

    enter image description here

    enter image description here

    Output:

    enter image description here

    With the output URL above, I clicked on the Authorize button.

    enter image description here

    I got the page below and clicked on the Authorize button.

    enter image description here

    It redirected me to pick an account for signing in. Then, I selected my account as shown below:

    enter image description here

    enter image description here

    Finally, I got the output below:

    enter image description here