我正在编写一个Web API。其中一项任务是使用Team Foundation Core DLLs访问Azure DevOps。由于我们是由Azure AD(Azure Active Directory)支持的,我认为可以让我的应用程序对Azure AD进行身份验证,并使用该令牌/授权来访问Azure DevOps。这不是唯一需要进行身份验证的服务。我能做到吗?还有其他方法可以实现此目标吗?我不想每次访问唯一的服务时都提示用户对Azure AD进行授权,尤其是它们都由Azure AD支持。
是的,你可以这样做。
注:我假设你的 API 是由 Azure AD 保护的,并且为了调用你的 API,用户需要使用 Azure AD 登录到你的 API 的客户端。
假设你希望你的 API 不仅向 Azure DevOps 发出请求,还要向 Microsoft Graph(以另一个由 Azure AD 保护的 API 为例--当然可以是你自己的第二个 API)发出请求,并且你希望这些请求代表已登录的用户。也就是说,代表在 API 接收到的访问令牌中识别的用户。
你可以进行以下操作(下面是图示):
+--------+ +-----------+ +-----------------+
(User)+---> +-(2)--> +-(4)---> |
| Client | | Your API <-------+ Azure DevOps |
| <------+ | | |
+----^---+ | +-(6)+ +-----------------+
| | | <--+ |
| | +---^----^--+ | | +-----------------+
(1) (3) (5) | +--> |
| | || || +----+ Microsoft Graph |
| | +--v----v--+ | (or other API) |
| +--------> | | |
| | Azure AD | +-----------------+
+----------+ |
+----------+
// 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!
login.microsoftonline.com/${appID}
。它应该只是login.microsoftonline.com
,还是我的Azure DevOps URI? - xtreampb.../{app-id}
,那样行不通。权限应该是https://login.microsoftonline.com/{tenant-id-or-domain-name}
。 - Philippe Signoret