-
Notifications
You must be signed in to change notification settings - Fork 214
Service to service calls on behalf of the user
Web API cannot have any user interaction, and therefore when a web API (labeled "first Web API") needs to call another Web API (named "second Web API") in the name of a user, it needs to use the "On Behalf Of" OAuth 2.0 flow, which is one of the flows described in details in Daemon or Server Application to Web API (along with the client credential flows that you have already seen).
This flow is a confidential client flow, and therefore the first web API provides client credentials (client secret or certificate), as seen in the previous paragraph. However, it will also provide another parameter named the userAssertion
: this time, the first web API will receive a bearer token and send it to Azure AD by embedding it into a user assertion to request another token to the downstream API.
The flow is explained in details in the following sample: https://github.com/Azure-Samples/active-directory-dotnet-webapi-onbehalfof and https://github.com/Azure-Samples/active-directory-dotnet-webapi-onbehalfof-ca, this last sample demonstrates how the middle Web API needs to process claims exceptions in the case of conditional access.
The code extracting the bearer token and creating the user assertion is available from TodoListController.cs#L138-L142
ClientCredential clientCred = new ClientCredential(clientId, appKey);
ClaimsPrincipal current = ClaimsPrincipal.Current;
var bootstrapContext = current.Identities.First().BootstrapContext
as System.IdentityModel.Tokens.BootstrapContext;
string userName = current.FindFirst(ClaimTypes.Upn) != null
? current.FindFirst(ClaimTypes.Upn).Value
: current.FindFirst(ClaimTypes.Email).Value;
string userAccessToken = bootstrapContext.Token;
UserAssertion userAssertion = new UserAssertion(userAccessToken,
"urn:ietf:params:oauth:grant-type:jwt-bearer",
userName);
The web API then acquires an access token for the downstream web API using the overrides of AcquireTokenAsync having a user assertion parameter as shown in TodoListController.cs#L158
try
{
result = await authContext.AcquireTokenSilentAsync(graphResourceId, clientId);
}
catch (AdalException adalException)
{
if (adalException.ErrorCode == AdalError.FailedToAcquireTokenSilently || adalException.ErrorCode == AdalError.UserInteractionRequired)
{
result = await authContext.AcquireTokenAsync(graphResourceId,
clientCred,
userAssertion);
}
}
See Handling ADAL.NET claim challenge exceptions See also Developer Guidance for Azure Active Directory Conditional Access
Sample | Platform | Description |
---|---|---|
active-directory-dotnet-webapi-onbehalfof | Desktop (WPF), SPA (JavaScript), Web API (ASP.NET MVC) | A .NET 4.5 MVC Web API protected by Azure AD that receives tokens from a client and uses ADAL to get tokens for calling the Microsoft Graph |
active-directory-dotnet-webapi-onbehalfof-ca | Desktop (WPF), SPA (JavaScript), Web API (ASP.NET MVC) | A .NET 4.5 MVC Web API protected by Azure AD that receives tokens from a client and uses ADAL to get tokens for calling a downstream web API with a Conditional Access policy applied to it. This is a variation of the previous sample to illustrate processing of Conditional access |
- Home
- Why use ADAL.NET?
- Register your app with AAD
- AuthenticationContext
- Acquiring Tokens
- Calling a protected API
- Acquiring a token interactively
- Acquiring tokens silently
- Using Device Code Flow
- Using Embedded Webview and System Browser in ADAL.NET and MSAL.NET
- With no user
- In the name of a user
- on behalf of (Service to service calls)
- by authorization code (Web Apps)
- Use async controller actions
- Exception types
- using Broker on iOS and Android
- Logging
- Token Cache serialization
- User management
- Using ADAL with a proxy
- Authentication context in multi-tenant scenarios
- Troubleshooting MFA in a WebApp or Web API
- Provide your own HttpClient
- iOS Keychain Access