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
[BUG/Question] Cross-origin token redemption is permitted only for the 'Single-Page Application' client-type. #47
Comments
Hi, The application created for OpenAPI seems to be configured for The application itself should looke something like this: "replyUrlsWithType": [
{
"url": "http://localhost:8000",
"type": "Web"
}
], and the OpenAPI application registration should look something like this: "replyUrlsWithType": [
{
"url": "http://localhost:8000/oauth2-redirect",
"type": "Spa"
}
], |
@JonasKs Huge Thanks! |
My pleasure 😊 |
Either request the scope for the token, such as (Sorry for formatting, written in a rush on my phone) |
@Vido I'm deleting and reposting your comment as it included potential sensitive information.
|
Hi guys, @JonasKs thanks for the swift answer. I can't get it to work... I guess there are something wrong with AD config. Consider this code. azure_scheme = SingleTenantAzureAuthorizationCodeBearer(
app_client_id=settings.APP_CLIENT_ID,
tenant_id=settings.TENANT_ID,
scopes={
# 'https://graph.microsoft.com/.default': 'default'
f'api://{settings.APP_CLIENT_ID}/user_impersonation': 'user_impersonation',
})
# I try this... same results
# @app.get("/", dependencies=[Security(azure_scheme, scopes=[])])
@app.get("/", dependencies=[Security(azure_scheme, scopes=["user_impersonation"])])
def read_root():
return "It works." I get 401 This is the underlining exception:
Am I missing something? |
Can you decode the token at e.g. jwt.io? The audience for the token is wrong. |
@JonasKs Huge Thanks again! The jwi.io tip was quite helpful. I wasn't aware that the JWT-token carried so much information. Thanks for your help. |
You’re welcome 😊 |
@JonasKs Hi, just one more question. (I don't think this worth to open a new issue.) Considering the same exemple of this Issue:
How to I get the authenticated user object (username, email, etc...) ? |
Hi @JonasKs , another silly question. Let's assume that the use case of the API is systems interoperability (ETLs, etc...), and not a SPA. Thanks. |
Hi, That's not a silly question! You would use something called Client Credentials flow. Basically just create a secret for your app reg and do something like this: from aiohttp import ClientSession
payload = {
'grant_type': 'client_credentials',
'client_id': client_id,
'client_secret': client_secret,
'scope': scope
}
async with ClientSession() as azure_client:
async with azure_client.post(f'https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token', data=payload) as azure_response:
azure_response = await azure_response.json()
token = azure_response['access_token']
print(token) or if you use httpx: from httpx import AsyncClient
payload = {
'grant_type': 'client_credentials',
'client_id': client_id,
'client_secret': client_secret,
'scope': scope
}
async with AsyncClient() as azure_client:
response = await azure_client.post(url=f'https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token', data=body)
token = response.json()['access_token']
print(token) If I don't remember wrong, you have to use the |
@JonasKs thanks again. This link about authentications protocols was quite helpful. In my use case, the API must be open to the internet, because business-costumers will get their data from it. |
Confidential means any service which is not exposed in any way. A place where the If authentication is done through the frontend (such as OpenAPI swagger docs or an SPA), you must use PKCE flow as described in the documentation. Between secure applications (such as you using |
@JonasKs. Thanks for the clarification.
Let's suppose: I have 100 business-costumers. The want to authenticate with a non-interactive (for easy of use). Do I have to share the client_secret among all of them? (Sounds messy). What are my alternatives for non-interactive clients? Another concern: |
Every application (confidential, secure client) would have their own application registration(appreg). That application has access to your backend. It's set up just like you would with the OpenAPI (Swagger) app registration. The users themself can get access to their appreg, and create their own secrets for their own application. No, you should not share secrets between applications. |
how do i overcome this, make it web instead of SPA? |
Not sure if I understand. You want the OpenAPI docs and other SPA applications (such as a JavaScript frontend) to be configured as SPA. I tested this flow last week, so if you follow the tutorial everything should work. |
Describe the bug
To Reproduce
This is the minimal FastAPI app:
Please, set the following envars:
Steps to reproduce the behavior:
Configuration
I believe this bug is related to my Azure AD set up, so may provide the Manifest from AD.
Sensitive information is hidden and the
<CENSORED>
is put in place.The text was updated successfully, but these errors were encountered: