Reputation: 562
I'm writing a web API. One of the things it does is hit Azure DevOps using the Team Foundation Core DLLs. As we are backed by Azure AD (Azure Active Directory) I was thinking that I could have my app authenticate against Azure AD and use that token/authorization for Azure DevOps. This isn't the only service that it is going to authenticate with. Can I do this? what other ways can I achieve this goal? I don't want to prompt the user to authorize against Azure AD each time it goes to hit a unique service, especially as they are all backed by Azure AD.
Upvotes: 3
Views: 4312
Reputation: 14336
Yes, you can do this.
Note: I'm assuming your API is secured by Azure AD, and that in order to call your API, users need to sign in to the client of your API with Azure AD.
Let's say you wanted your API to make requests not only to Azure DevOps, but also to Microsoft Graph (to take an example of another API secured by Azure AD--this could of course be any other API, including a second API of your own), and that you wanted those requests to be on behalf of the signed-in user. That is, on behalf of the user who is identified in the access token received by the API.
You could do the following (diagram below):
+--------+ +-----------+ +-----------------+
(User)+---> +-(2)--> +-(4)---> |
| Client | | Your API <-------+ Azure DevOps |
| <------+ | | |
+----^---+ | +-(6)+ +-----------------+
| | | <--+ |
| | +---^----^--+ | | +-----------------+
(1) (3) (5) | +--> |
| | || || +----+ Microsoft Graph |
| | +--v----v--+ | (or other API) |
| +--------> | | |
| | Azure AD | +-----------------+
+----------+ |
+----------+
The detailed token flow is described in the Azure AD documentation (for both the v1 endpoint and the v2 endpoint).
Of course, all the complexities here, as well as token caching and refreshing, should be handled by simple libraries such as ADAL or MSAL, both of which have wiki pages for the on-behalf-of flow (with ADAL, with MSAL). Here's a summarized example of what it looks like with ADAL (taken from the To
// Use ADAL to get a token On Behalf Of the current user. To do this we will need:
// The Resource ID of the service we want to call.
// The current user's access token, from the current request's authorization header.
// The credentials of this application.
// The username of the user calling the API
//
string resourceId = "499b84ac-1321-427f-aa17-267ca6975798"; // this is the Azure DevOps app ID
string userName = "...";// get from incoming token
string userAccessToken = "..." // from incoming Authorization header;
UserAssertion userAssertion = new UserAssertion(userAccessToken, "urn:ietf:params:oauth:grant-type:jwt-bearer", userName);
ClientCredential clientCred = new ClientCredential(clientId, appKey);
AuthenticationContext authContext = new AuthenticationContext(authority, tokenCache);
// Now make the on-behalf-of request
result = await authContext.AcquireTokenAsync(resourceId, clientCred, userAssertion);
accessToken = result.AccessToken; // <-- this is a token for Azure DevOps!
Upvotes: 5