Ask Learn
Preview
Ask Learn is an AI assistant that can answer questions, clarify concepts, and define terms using trusted Microsoft documentation.
Please sign in to use Ask Learn.
Sign inThis browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
tl;dr
"Hello World"!
Protect a web resource with Azure AD is really easy and well documented, but in a delegation scenario where we need to access to an external resource impersonating the signed-in user the things can get little more complicated.
Is not difficult, we just need few extra steps and configuration from the base case.
If I would like to implement an architecture as the following:
As you know the first time we access a resource protected by an Oauth based protocol (like OpenIDConnect in AAD) we need to "visually" grant the access to that resource. The classic HTML page that requires the user input to continue. Because at step 2/b we specified the FrontEnd app needs to access the Api app the user will be prompted to confirm the access to both applications (FrontEnd + Api) in a single page.
By default the ADAL library uses the OpenIDConnect "authorization code flow". This means that the FrontEnd app receives an authorization code as part of the login process. This authorization code can be reedemed and exchanged for an access token for the Api app. With ADAL this task can be done in the AuthorizationCodeReceived notification event (in Startup.Auth.cs).
So far so good. We have authenticated the user, received an id_token that identifies the caller, reedemed the authorization code and obtained the access_token for the Api layer. Thus we can access the Api app as the calling user.
Unfortunately this is not sufficent if the Api app needs to access an external resource acting as the signed in user (third hop). This because the token received from this layer is meant only to the Api app and cannot be used to access the external resource (i.e: Microsoft Graph). We need a specific token for this latter resource but there are two major issues at this point:
In any case we also would like to silently access this resource in a SSO manner without asking again for credentials. Basically we need a way to grant the access to the external resource via the Api layer upfront. Fortunately this is possible manually editing the registration manifest for the Api app in the Azure portal:
"knownClientApplications": ["XXXXXX-YYYY-ZZZZZZ-WWWWW-XXXXXXX"]
Adding the GUID of the FrontEnd app to the "knownClientApplications" property we link the two registrations. This means the first time the user access the FrontEnd app, he will be prompted to grant the access for all the permissions specified by both apps and not only by the FrontEnd one. In other words, we obtain a consensus page that lists all the permissions and all the external resources accessed by the current application and all the linked ones.
Now, as the user grants the access to all the resources upfront, the Api app can request a token for the external resource in a SSO manner. In this case we need to use the "On-Behalf-Of flow" that allows to get an access token that delegates the user credentials. To successfully request this kind token we need to:
if you are using ADAL this translates in two simple steps:
UserAssertion userAssertion = new UserAssertion(bootstrapContext, "urn:ietf:params:oauth:grant-type:jwt-bearer", userName);
var result = await authContext.AcquireTokenAsync(resourceUri, clientCred, userAssertion);
Ask Learn is an AI assistant that can answer questions, clarify concepts, and define terms using trusted Microsoft documentation.
Please sign in to use Ask Learn.
Sign in