AzureAD / microsoft-authentication-library-for-python

Microsoft Authentication Library (MSAL) for Python makes it easy to authenticate to Microsoft Entra ID. General docs are available here https://learn.microsoft.com/entra/msal/python/ Stable APIs are documented here https://msal-python.readthedocs.io. Questions can be asked on www.stackoverflow.com with tag "msal" + "python".
https://stackoverflow.com/questions/tagged/azure-ad-msal+python
Other
770 stars 192 forks source link

Assertion failed signature validation when trying to acquire a token to issue REST calls to dev ops on behalf of a user #468

Closed flixman closed 2 years ago

flixman commented 2 years ago

Describe the bug I have an azure app, having granted the 'impersonate_user' permission, that needs to be able to perform calls to azure devops on behalf of the user. Instead of getting a token allowing me to do so, I get an error. Am I missing a permission on the app, am I doing something wrong, or this is a bug?

To Reproduce Just use the following snippet with the correspondent access token, client_id, client_secret and tenant parameters.

import msal
confidential_client = msal.ConfidentialClientApplication(
            <client_id>,
            authority="https://login.microsoftonline.com/<tenant>",
            client_credential=<cliend_secret>)
devops_token = confidential_client.acquire_token_on_behalf_of(
            user_assertion=request.headers.get("X-Ms-Token-Aad-Access-Token"),
            scopes=["499b84ac-1321-427f-aa17-267ca6975798/user_impersonation"])

Expected behavior A token in that I can use to authenticate to azure devops.

What you see instead The error _invalidgrant and the description"ADSTS50013: Assertion failed signature validation. [Reason - The provided signature value did not match the expected signature value., Thumbprint of key used by client: '8D2D57A353960E3FF9DAF6F018D82F40ED95CCC7', Found key 'Start=01/30/2022 23:06:14, End=01/30/2027 23:06:14']."

The MSAL Python version you are using 1.17.0

rayluo commented 2 years ago

Your calling pattern seems about right. I can't tell whether it was some configuration issues. Some reference materials for you:

KanishkaB commented 2 years ago

@flixman - You have a python web app that needs to access the azure dev ops API. You have deployed this app on azure app service and are currently using the built in authentication feature of App Service aka EasyAuth. The value of the access token generated from EasyAuth is actually an "authentication code" and when the resource is set, the EasyAuth module exchanges this “authentication code” at the /token endpoint of the Azure Active Directory, to get an access token. We ran couple of tests at your end and figured out that the scope - user_impersonation was not set at the resource level.

Work Around - To achieve this we need to set the resource using the Azure Resource Explorer.

  1. Navigate to the Resource Explorer from the App Service.
  2. Navigate config > authsettings and click on Edit.
  3. Update the additionalLoginParams to ["resource=<Name/ID of the resource>"] Once this is set you should be able to access the Azure dev ops API.

Recommendation - we highly recommend you to use MSAL python in your application code so that the authentication can be handled at the application level This Web application will use MSAL for Python to sign-in a user and obtains an Access Token for API ( Azure dev ops in your case ) from Azure AD. The Access Token will prove that the user is authorized to access the API endpoint as defined in the scope. .You can refer to the below sample for reference GitHub - Azure-Samples/ms-identity-python-flask-webapp-call-graph: Python Flask web application that leverages MSAL Python to get an access token to call MS Graph API Please let us know in case you have any further questions or queries and we will be happy to answer.