I have two application registrations: one for the backend and one for the frontend.
On the backend App Reg, I have defined (exposed) a scope called User_impersonation
like the following:
On the frontend App Reg, I have added the permissions (User_impersonation) like the following:
Also on the frontend side, I enabled user/group assignment and assigned a security group; so that only the members of that security group can access/query this frontend.
So far, when a user queries the frontend with an access token (requested from the frontend app reg); everything works fine: the frontend app reg requests an access token from the backend and forwards the request of the user.
However, when I try to enable the user/group assignment on the backend app reg (by adding the same security group); the frontend app can no longer query the backend (User_impersonation fails); like the query times out with no reply from the backend.
Can someone help me make the User_impersonation work when the group assignment is enabled on both app regs (not only the frontend). Thanks.
This is how the client/user requests access to the webapp/frontend:
from azure.identity import DefaultAzureCredential, ClientSecretCredential
authority="https://login.microsoftonline.com/{TENANT_ID}/v2.0"
credential = DefaultAzureCredential(authority=authority, exclude_shared_token_cache_credential=True)
scope = "api://{frontend_clientid}/.default"
minerva_webapp_access_token = credential.get_token(scope).token
and this is how the webapp/frontend requests access to the backend app reg:
credential = ClientSecretCredential(
tenant_id=TENANT_ID,
client_id=WEBAPP_CLIENT_ID,
client_secret=webapp_client_secret)
scope = ( "api://{minerva_python39_backend_app_client_id}/.default".format(
minerva_python39_backend_app_client_id=MINERVA_PYTHON39_CLIENTID))
access_token = credential.get_token(scope).token
Note that, client credentials flow works only with permissions of
Application
type. This flow won't work withUser_impersonation
as it is Delegated permission.
I registered 2 applications in my Azure AD tenant same as you: one for the backend and one for the frontend.
On the Backend application, I defined (exposed) User_impersonation
scope like below:
On the Frontend application, I added User_impersonation
API permission:
Now, I generated access token using client credentials with same code as you like below:
credential = ClientSecretCredential(
tenant_id=TENANT_ID,
client_id=WEBAPP_CLIENT_ID,
client_secret=webapp_client_secret)
scope = ( "api://{minerva_python39_backend_app_client_id}/.default".format(
minerva_python39_backend_app_client_id=MINERVA_PYTHON39_CLIENTID))
access_token = credential.get_token(scope).token
print(access_token)
Response:
When I decode the token by pasting it in jwt.ms, it has right audience in aud
but missing scp
claim like below:
To make
User_impersonation
work when the group assignment is enabled on both app regs, your access token should havescp
claim with that specific permission.For that, you need to use Delegated flows like authorization code flow, interactive flow, username password flow etc... for generating tokens.
In my case, I used authorization code flow to generate access token for which code is needed. I ran below authorization request in browser and got code successfully in address bar:
https://login.microsoftonline.com/<tenantId>/oauth2/v2.0/authorize?
client_id=<frontend_appId>
&redirect_uri=https://jwt.ms
&response_type=code
&response_mode=query
&scope= api://<backend_appID>/User_impersonation
&state=12345
Code:
I ran below python code and got access token using authorization code flow in response like this:
from azure.identity import AuthorizationCodeCredential
credential = AuthorizationCodeCredential(
tenant_id=TENANT_ID,
client_id=WEBAPP_CLIENT_ID,
authorization_code="<auth_code_from_above>",
redirect_uri="https://jwt.ms",
)
scope = ( "api://{minerva_python39_backend_app_client_id}/.default".format(
minerva_python39_backend_app_client_id=MINERVA_PYTHON39_CLIENTID))
access_token = credential.get_token(scope).token
print(access_token)
Response:
When I decode the token by pasting it in jwt.ms, it has right audience in aud
and User_impersonation permission in scp
claim like below:
In your case, decode whether the token has User_impersonation permission in scp
claim and change to Delegated flows for generating token to access backend as I mentioned.