Giter Site home page Giter Site logo

Comments (22)

Prmurray avatar Prmurray commented on June 14, 2024 1

Well I'm a fool. I misnamed my .env file. it was just env. and since I saw an issue left on the repo 3 hours before I ran into the problem, I just assumed my code was right and something changed in the repo. After renaming the file, everything worked correctly.
sorry for wasting your time. It's an excellent tutorial and an awesome library, thanks for your work.

from fastapi-azure-auth.

davidhuser avatar davidhuser commented on June 14, 2024 1

I don't use it myself yet but thought it might be good to do a little digging. According to
Set up OAuth 2.0 client credentials flow in Azure Active Directory B2C (which is in preview by the way), you need to alter your URL and the scope. Here is what I used to get a valid token and auth to the B2C protected FastAPI app:

import json
from typing import Union

from httpx import AsyncClient
import asyncio

# change to your own method:
settings = get_settings()

CLIENT_SECRET = 'xxx'  # the secret you created
API_URL = 'https://path-to-my-app/api'  # the URL of the FastAPI
ENDPOINT = 'myEndpoint'  # the endpoint you want to call


async def get_token(client: AsyncClient) -> Union[str, None]:
    url = f"https://{settings.TENANT_NAME}.b2clogin.com/{settings.TENANT_NAME}.onmicrosoft.com/{settings.AUTH_POLICY_NAME}/oauth2/v2.0/token"

    headers = {"Content-Type": "application/x-www-form-urlencoded"}

    data = {
        "client_id": settings.APP_CLIENT_ID,
        "scope": f'https://{settings.TENANT_NAME}.onmicrosoft.com/{settings.APP_CLIENT_ID}/.default',
        "client_secret": CLIENT_SECRET,
        "grant_type": "client_credentials",
    }

    r = await client.post(url, headers=headers, data=data)

    if r.status_code == 200:
        token = json.loads(r.text)["access_token"]
        return token
    else:
        print(f"Failed to get token, status code: {r.status_code}, message: {r.text}")
        return None


async def call_api(client: AsyncClient, token: str):
    r = await client.get(f"{API_URL}/{ENDPOINT}", headers={"Authorization": f"Bearer {token}"})

    if r.status_code == 200:
        print(r.text)
    else:
        print(f"Failed to call API, status code: {r.status_code}, message: {r.text}")


async def main():
    async with AsyncClient() as client:
        token = await get_token(client)
        if token:
            print("Token:", token)
            await call_api(client, token)


asyncio.run(main())

Let us know if it works.

from fastapi-azure-auth.

davidhuser avatar davidhuser commented on June 14, 2024 1

the root cause is not yet clear to me because we don't have the info of the error. Can you check if you can log fastapi_azure_auth DEBUG messages to your FastAPI logger?

Here's a starting point for debugging.

import logging
from fastapi import FastAPI

# Configure root logger
logging.basicConfig(level=logging.DEBUG)

# Set logging level for library
logging.getLogger('fastapi_azure_auth').setLevel(logging.DEBUG)

# Ensure logs are propagated
logging.getLogger('fastapi_azure_auth').propagate = True

app = FastAPI()

@app.get("/")
def read_root():
    return {"Hello": "World"}

edit: changed to DEBUG

from fastapi-azure-auth.

JonasKs avatar JonasKs commented on June 14, 2024 1

We should probably add a troubleshooting section (like I have for my Django package)in the docs and make an issue template.

Thanks for all your contributions, help and reviews @davidhuser.😊

from fastapi-azure-auth.

davidhuser avatar davidhuser commented on June 14, 2024 1

ah got it, great that it works now. I see the docs use OPENAPI_CLIENT_ID as the secret was created for that app reg.

Will add two doc PRs for "Calling the APIs with Python" and a "troubleshooting" page.

from fastapi-azure-auth.

JonasKs avatar JonasKs commented on June 14, 2024

Please provide full code snippets and error messages.
Also provide screenshot of how your backend API tokens have been exposed.
Also please provide which tenant type you're using. Single-, multi- or B2C-tenant?
I suspect you've gone off track from the tutorial, and then have alterations you need to do.
I suggest, when experiencing issues, that you follow the tutorial 100% and test if it works, and then slowly alter.

from fastapi-azure-auth.

Prmurray avatar Prmurray commented on June 14, 2024

I ran into this problem today as well. Everything was working for me on Wednesday. Ill work on getting some better screenshots, but it looks like the clientID is not being added to the authorization URL
image
(I know the scope is spelled incorrectly, that's how the scope is spelled in my app though)

from fastapi-azure-auth.

JonasKs avatar JonasKs commented on June 14, 2024

I'm really confused here - something worked on Wednesday no longer works today?

Can you please give me some errors or context here? I haven't changed anything in this library for a while.
Did Azure change something? 🤔

from fastapi-azure-auth.

Prmurray avatar Prmurray commented on June 14, 2024

image

this error pops up (while running uvicorn) as soon as I add this section to the code:
@app.on_event('startup')
async def load_config() -> None:
"""
Load OpenID config on startup.
"""
await azure_scheme.openid_config.load_config()

when I take that section of code out, I am able to enter my authorization credentials, but when I submit them I'm met with this page:

image

It's not adding the app information, it's trying to load "https://login.microsoftonline.com//oauth2/v2.0/authorize?"

from fastapi-azure-auth.

JonasKs avatar JonasKs commented on June 14, 2024

Glad you solved it. Thanks for the kind words 😊

from fastapi-azure-auth.

mehtatejas avatar mehtatejas commented on June 14, 2024

Please provide full code snippets and error messages. Also provide screenshot of how your backend API tokens have been exposed. Also please provide which tenant type you're using. Single-, multi- or B2C-tenant? I suspect you've gone off track from the tutorial, and then have alterations you need to do. I suggest, when experiencing issues, that you follow the tutorial 100% and test if it works, and then slowly alter.

I am using B2C tenant.
I went through following URL:
https://intility.github.io/fastapi-azure-auth/b2c/azure_setup
https://intility.github.io/fastapi-azure-auth/b2c/fastapi_configuration
Documentation and tutorial were excellent.
I created two applications:

image

I can authenticate FastAPI using Azure AD B2C.

I want to expose my FastAPI from other Python.

Hence I followed following URL :
https://intility.github.io/fastapi-azure-auth/usage-and-faq/calling_your_apis_from_python

I created client secret in fastapi-az-b2c-api-OpenAPI application.

Please find by code below

  from httpx import AsyncClient
  from config import settings
  import asyncio
  
  async def fn():
      async with AsyncClient() as client:

        azure_response = await client.post(
            url=f'https://login.microsoftonline.com/{settings.TENANT_ID}/oauth2/v2.0/token',
            data={
                'grant_type': 'client_credentials',
                'client_id': settings.OPENAPI_CLIENT_ID,  # the ID of the app reg you created the secret for
                'client_secret': settings.CLIENT_SECRET,  # the secret you created
                'scope': f'api://{settings.APP_CLIENT_ID}/.default',  # note: NOT .user_impersonation
            }
        )

        # print(azure_response)
        print(azure_response.json())
        # token = azure_response.json()['access_token']

        # print(token)
        # my_api_response = await client.get(
        #     'http://localhost:8000/',
        #     headers={'Authorization': f'Bearer {token}'},
        # )
        # print(my_api_response.json())


asyncio.run(fn())

Now I am getting following error :

error

Please let me know, if I am missing anything.

from fastapi-azure-auth.

JonasKs avatar JonasKs commented on June 14, 2024

Hmm.. @davidhuser , do you know if there's something specific for B2C? 🤔

from fastapi-azure-auth.

davidhuser avatar davidhuser commented on June 14, 2024

Note that this is still valid

in reality you should create a new app registration for every application talking to your backend.
https://intility.github.io/fastapi-azure-auth/usage-and-faq/calling_your_apis_from_python

from fastapi-azure-auth.

mehtatejas avatar mehtatejas commented on June 14, 2024

I don't use it myself yet but thought it might be good to do a little digging. According to Set up OAuth 2.0 client credentials flow in Azure Active Directory B2C (which is in preview by the way), you need to alter your URL and the scope. Here is what I used to get a valid token and auth to the B2C protected FastAPI app:

import json
from typing import Union

from httpx import AsyncClient
import asyncio

# change to your own method:
settings = get_settings()

CLIENT_SECRET = 'xxx'  # the secret you created
API_URL = 'https://path-to-my-app/api'  # the URL of the FastAPI
ENDPOINT = 'myEndpoint'  # the endpoint you want to call


async def get_token(client: AsyncClient) -> Union[str, None]:
    url = f"https://{settings.TENANT_NAME}.b2clogin.com/{settings.TENANT_NAME}.onmicrosoft.com/{settings.AUTH_POLICY_NAME}/oauth2/v2.0/token"

    headers = {"Content-Type": "application/x-www-form-urlencoded"}

    data = {
        "client_id": settings.APP_CLIENT_ID,
        "scope": f'https://{settings.TENANT_NAME}.onmicrosoft.com/{settings.APP_CLIENT_ID}/.default',
        "client_secret": CLIENT_SECRET,
        "grant_type": "client_credentials",
    }

    r = await client.post(url, headers=headers, data=data)

    if r.status_code == 200:
        token = json.loads(r.text)["access_token"]
        return token
    else:
        print(f"Failed to get token, status code: {r.status_code}, message: {r.text}")
        return None


async def call_api(client: AsyncClient, token: str):
    r = await client.get(f"{API_URL}/{ENDPOINT}", headers={"Authorization": f"Bearer {token}"})

    if r.status_code == 200:
        print(r.text)
    else:
        print(f"Failed to call API, status code: {r.status_code}, message: {r.text}")


async def main():
    async with AsyncClient() as client:
        token = await get_token(client)
        if token:
            print("Token:", token)
            await call_api(client, token)


asyncio.run(main())

Let us know if it works.

I am now getting following error :

Failed to call API, status code: 401, message: {"detail":"Token contains invalid claims"}

from fastapi-azure-auth.

davidhuser avatar davidhuser commented on June 14, 2024

Looks like you got a token but the library raised an JWTClaimsError when calling the endpoint.

https://github.com/Intility/fastapi-azure-auth/blob/main/fastapi_azure_auth/auth.py#L213

any more info in your FastApi app logs?

from fastapi-azure-auth.

JonasKs avatar JonasKs commented on June 14, 2024

Also please decode the token at jwt.io and show the decoded version to us (You can redact the names etc of course)

Also, for the future, please add as much information to every post/question you can. Eventually those who help you stop asking questions, which ends up in you not getting help. Enable debug logs, show entire stack traces, explain your entire environment. Makes this so much easier for all of us 😊

from fastapi-azure-auth.

mehtatejas avatar mehtatejas commented on June 14, 2024

@davidhuser and @davidhuser.
Please find response from jwt.io and fastapi logs.

error_15Oct2023

image

from fastapi-azure-auth.

mehtatejas avatar mehtatejas commented on June 14, 2024

@davidhuser : Please find below debug log:

error_17Oct2023

I agree, troubleshooting section will be very helpful. Specially, Azure AD B2C.

Thanks @davidhuser and @JonasKs for help.

from fastapi-azure-auth.

davidhuser avatar davidhuser commented on June 14, 2024

thanks for showing us the debug logs. as per logs, nbf is a timestamp for "not before", see https://learn.microsoft.com/en-us/azure/active-directory-b2c/tokens-overview#claims
so it seems your local computer is out of sync with Azure. Can you check your machine's time clock? e.g. others had issues with WSL clock https://stackoverflow.com/q/68997594

from fastapi-azure-auth.

JonasKs avatar JonasKs commented on June 14, 2024

Agree.

We can also add a leeway-setting, it's been hard coded to 0 atm.

Someone had a similar issue last month.

from fastapi-azure-auth.

mehtatejas avatar mehtatejas commented on June 14, 2024

I did following changes:

  • 'leeway': 7
  • client_id from APP_CLIENT_ID to OPENAPI_CLIENT_ID

data = { "client_id": settings['OPENAPI_CLIENT_ID'], "scope": f"https://{settings['TENANT_NAME']}.onmicrosoft.com/{settings['APP_CLIENT_ID']}/.default", "client_secret": settings['CLIENT_SECRET'], "grant_type": "client_credentials", }

It worked.

@davidhuser & @JonasKs : Thank you very much for support.

from fastapi-azure-auth.

JonasKs avatar JonasKs commented on June 14, 2024

Glad you solved it.

I've added a new issue for allowing the settings to be set. PRs welcome.

from fastapi-azure-auth.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.