我正在编写一个Web API。它要做的一件事是使用Team Foundation Core DLL击中Azure DevOps。当我们得到Azure AD(Azure Active Directory)的支持时,我在想我可以使我的应用程序针对Azure AD进行身份验证,并将该令牌/授权用于Azure DevOps。这不是要进行身份验证的唯一服务。我可以这样做吗?我还能通过哪些其他方式实现这一目标?我不想在每次用户访问唯一服务时都提示用户针对Azure AD授权,特别是因为它们都由Azure AD支持。
答案 0 :(得分:2)
是的,您可以这样做。
注意:我假设您的API受Azure AD保护,并且为了调用您的API,用户需要使用Azure AD登录到API的客户端。
假设您希望您的API不仅向Azure DevOps发出请求,而且还向Microsoft Graph发出请求(以由Azure AD保护的另一个API为例-当然可以是任何其他API,包括第二个API您自己的),并且您希望这些请求代表登录用户。也就是说,代表由API接收的访问令牌中标识的用户。
您可以执行以下操作(如下图):
+--------+ +-----------+ +-----------------+
(User)+---> +-(2)--> +-(4)---> |
| Client | | Your API <-------+ Azure DevOps |
| <------+ | | |
+----^---+ | +-(6)+ +-----------------+
| | | <--+ |
| | +---^----^--+ | | +-----------------+
(1) (3) (5) | +--> |
| | || || +----+ Microsoft Graph |
| | +--v----v--+ | (or other API) |
| +--------> | | |
| | Azure AD | +-----------------+
+----------+ |
+----------+
Azure AD文档(针对v1 endpoint和v2 endpoint)中都描述了详细的令牌流。
当然,这里的所有复杂性以及令牌缓存和刷新都应由ADAL或MSAL之类的简单库处理,它们都具有代表代流程的Wiki页面({{3} },with ADAL)。这是ADAL的摘要示例(摘自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!