-
Notifications
You must be signed in to change notification settings - Fork 61
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
[Question/Documentation]: Example showing how to call MS Graph API #40
Comments
Hi! I’m afraid not. I still haven’t used the Graph API. |
If anyone has used the Graph API and would like to contribute to the documentation with a little tutorial, that would be greatly appreciated. 🚀 |
I got the following error when trying to call the Microsoft Graph API using the access token coming from the User object: {'error': {'code': 'InvalidAuthenticationToken', 'message': 'Invalid x5t claim.', 'innerError': {'date': '2022-03-31T03:16:06', 'request-id': 'ee81c3f0-f21
d-44d6-a7bd-c91bdd102971', 'client-request-id': 'ee81c3f0-f21d-44d6-a7bd-c91bdd102971'}}} After reading this: https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/resources-and-scopes.md, I realized it's related to how the scopes work in AzureAD. So I tried adding the User.Read scope to both the Backend and OpenAPI apps, and then only selecting this scope in the login pop-up in the OpenAPI docs. But I got the following response: {
"detail": "Unable to validate token"
} And this is the error stack: Invalid token. Error: Signature verification failed.
Traceback (most recent call last):
File "c:\users\me\.virtualenvs\x-lru6flmw\lib\site-packages\jose\jws.py", line 262, in _verify_signature
raise JWSSignatureError()
jose.exceptions.JWSSignatureError
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "c:\users\me\.virtualenvs\x-lru6flmw\lib\site-packages\jose\jwt.py", line 142, in decode
payload = jws.verify(token, key, algorithms, verify=verify_signature)
File "c:\users\me\.virtualenvs\x-lru6flmw\lib\site-packages\jose\jws.py", line 73, in verify
_verify_signature(signing_input, header, signature, key, algorithms)
File "c:\users\me\.virtualenvs\x-lru6flmw\lib\site-packages\jose\jws.py", line 264, in _verify_signature
raise JWSError("Signature verification failed.")
jose.exceptions.JWSError: Signature verification failed.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "c:\users\me\.virtualenvs\x-lru6flmw\lib\site-packages\fastapi_azure_auth\auth.py", line 183, in __call__
token = jwt.decode(
File "c:\users\me\.virtualenvs\x-lru6flmw\lib\site-packages\jose\jwt.py", line 144, in decode
raise JWTError(e)
jose.exceptions.JWTError: Signature verification failed. I don't know how to proceed from this point 😅 |
Yeah, I've never actually tried this. It seems from the link you sent that:
I believe, that this means the same would work the opposite way, where if you selected your application scope ( I have a packed day today, but I'll see if I find some time tonight or this weekend. 😊 |
A token with the wrong audience (for Graph) will always be denied, and that's what you see when you get this error:
Pasting the token into jwt.io will show you that the The token with the correct async with AsyncClient() as client:
data = {
'grant_type': 'urn:ietf:params:oauth:grant-type:jwt-bearer',
'client_id': settings.APP_CLIENT_ID,
'client_secret': settings.GRAPH_SECRET,
'assertion': request.state.user.access_token,
'scope': 'https://graph.microsoft.com/user.read',
'requested_token_use': 'on_behalf_of'
}
response = await client.post('https://login.microsoftonline.com/<tenant id>/oauth2/v2.0/token', data=data) with the secret created for the backend appreg. However, this still gives me an error: {'error': 'invalid_grant', 'error_description': "AADSTS65001: The user or administrator has not consented to use the application with ID '<application id>' named 'FastAPI-Azure-Auth-DemoProj'. Send an interactive authorization request for this user and resource.", 'error_codes': [65001], 'suberror': 'consent_required'} which I don't understand, since I consent to that on login, and can confirm by checking the Enterprise Application for the OpenAPI appreg: The token does not have the User.Read scope in it, even when using Any tips or tricks we should check out @h3rmanj ? |
I also tried adding "knownClientApplications": [
"00000003-0000-0000-c000-000000000000"
], to my manifests, but didn't help :/ |
I pushed a graph debug branch if someone want to look over the code and give it a shot themselves. I still haven't been able to make it work. Click for instructions
To attempt different scopes, see |
@JonasKs I got this result {
"access_token": "eyJ0eXAiOiJKV1QiLCJub25jZSI6IkNndDNnRDhidDYxZ18yUkpvZmZFSmhnMlRUZHhoa2E3Q3JLUVNMcWNGVjAiLCJhbGciOiJSUzI1NiIsIng1dCI6ImpTMVhvMU9XRGpfNTJ2YndHTmd2UU8yVnpNYyIsImtpZCI6ImpTM",
"token_type": "Bearer",
"scope": "profile openid email https://graph.microsoft.com/User.Read",
"expires_in": 4431,
"ext_expires_in": 4431
} Does this mean success? EDIT: I tried calling the Microsoft Graph API with the token and, yeah, I got the result. |
Using OBO? 🎉 How's your appregs set up? I'd love to make it work for me too so I can write docs for it (PRs welcome!😊) Edit: I removed your access token from your message. |
Yeah 🎊 , I only change this part from your code response = await client.post('https://login.microsoftonline.com/<tenant id>/oauth2/v2.0/token', data=data) I use the tenant ID of Backend API appregs instead of the OpenAPI I think the rest of the configuration is the same.
Thank you so much! |
Alright, thank you! I don’t have that green check box after User.Read so I’ll have to look into that. You’re saying your appregs are the exact same as my tutorial told you to set them up? 😊 |
Thank you!
Yep! I only create new client secrets because I did not have it previously. |
Ah yeah, I think you're correct! I tried revoking the admin consent and I got the same error as you now: {
"error": "invalid_grant",
"error_description": "AADSTS65001: The user or administrator has not consented to use the application with ID 'edd67d27-ce10-4252-8f5e-2d7b7a4bbe90' named 'BE'. Send an interactive authorization request for this user and resource.\r\nTrace ID: ca86ff3c-77b2-4874-a372-affd83d46500\r\nCorrelation ID: 71ed2675-cc1b-472a-a5fa-251b63134f98\r\nTimestamp: 2022-04-04 07:29:13Z",
"error_codes": [
65001
],
"timestamp": "2022-04-04 07:29:13Z",
"trace_id": "ca86ff3c-77b2-4874-a372-affd83d46500",
"correlation_id": "71ed2675-cc1b-472a-a5fa-251b63134f98",
"suberror": "consent_required"
} |
Just got granted admin consent now and everything works here too! Thanks for troubleshooting this with me! I'll make sure to add some helper functions and documentation on how this works. |
Hi! Using delegated permissions should not require admin consent (unless specified in Azure AD). I tested a setup with .NET (should be the same for fastapi, the important thing is consent and app configuration), and got it to work with only user consent. To make this work we need some configuration in Azure AD. The Swagger app registrations needs the following permissions:
The API app registration needs to:
In Swagger, you have to configure the authentication request to get the You can now use the OBO3 flow as expected. Footnotes
|
Thank you @h3rmanj ❤️
I initially thought I messed up this step, but I had both the swagger app client ID and the Graph client ID in there. So not sure why it didn't work for me yesterday. Maybe updating manifests are slow (like they can be with v1 -> v2 swap)? I never attempted again today before I got admin consent. Anyway, on a fresh app registration everything worked as you described. I'll write some docs. 🎉 |
- #62: Tutorial on how to use Python to interact with your APIs - #61: Tutorial on how to access user attributes in your APIs - #45: Added a page that explains how to solve admin consent when signing in. Thank you @bkmetzler - #40: Add tutorial on how to set up and use Graph APIs using the On Behalf Flow. Thank you @u-iandono & @h3rmanj - Add graph endpoint example
- #62: Tutorial on how to use Python to interact with your APIs - #61: Tutorial on how to access user attributes in your APIs - #45: Added a page that explains how to solve admin consent when signing in. Thank you @bkmetzler - #40: Add tutorial on how to set up and use Graph APIs using the On Behalf Flow. Thank you @u-iandono & @h3rmanj - Add graph endpoint example
Thank you so much, both of you! I've added documentation here. |
Thank you so much @JonasKs ! |
- Intility#62: Tutorial on how to use Python to interact with your APIs - Intility#61: Tutorial on how to access user attributes in your APIs - Intility#45: Added a page that explains how to solve admin consent when signing in. Thank you @bkmetzler - Intility#40: Add tutorial on how to set up and use Graph APIs using the On Behalf Flow. Thank you @u-iandono & @h3rmanj - Add graph endpoint example
Documentation, closes Intility#40, Intility#45, Intility#61, Intility#62
Was wondering if there were any examples of showing how to use the token to call the MS Graph API?
The text was updated successfully, but these errors were encountered: