Bre*_*gby 6 c# azure azure-active-directory asp.net-core
我很难理解如何重用用户的安全令牌,以在他们的数据请求流经多个Web API时对其进行身份验证。
Console App
-C#/ Net Framework 4.7.x控制台应用程序。WebAPI 1
-C#/ .Net Core 2.2 MVC WebAPI应用程序。WebAPI 2
-C#/ .Net Core 2.2 MVC WebAPI应用程序。当前,它们都在自己的Visual Studio 2019解决方案中配置为独立的应用程序,这些解决方案在我的开发箱上运行,但是(一旦运行!)将各自作为独立的实体托管在Azure中。
本质上,用户在控制台应用程序中进行身份验证,从而从Azure Active Directory验证其凭据。在GitHub上的此示例之后,我已经WebAPI 1
成功完成了我的Console App的调用,并返回了数据。
但是,我想WebAPI 1
在通话WebAPI 2
期间进行调用,并检索其他数据作为Console App数据集的一部分,而这正是我所坚持的部分。
WebAPI 2
在Azure门户中的配置与完全相同WebAPI 1
,但不同的应用程序客户端ID等除外。
作为样本的一部分(如上所述),WebAPI 1
在将数据返回给调用之前,我可以取消Microsoft的Graph API Console App
,所以我认为我没有办法。这是调用Graph API的代码:
public async Task<string> CallGraphApiOnBehalfOfUser()
{
string[] scopes = { "user.read" };
// we use MSAL.NET to get a token to call the API On Behalf Of the current user
try
{
string accessToken = await _tokenAcquisition.GetAccessTokenOnBehalfOfUser(HttpContext, scopes);
dynamic me = await CallGraphApiOnBehalfOfUser(accessToken);
return me.userPrincipalName;
}
catch (MsalUiRequiredException ex)
{
_tokenAcquisition.ReplyForbiddenWithWwwAuthenticateHeader(HttpContext, scopes, ex);
return string.Empty;
}
}
private static async Task<dynamic> CallGraphApiOnBehalfOfUserOriginal(string accessToken)
{
//
// Call the Graph API and retrieve the user's profile.
//
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
HttpResponseMessage response = await client.GetAsync("https://graph.microsoft.com/v1.0/me");
string content = await response.Content.ReadAsStringAsync();
if (response.StatusCode == HttpStatusCode.OK)
{
dynamic me = JsonConvert.DeserializeObject(content);
return me;
}
throw new Exception(content);
}
Run Code Online (Sandbox Code Playgroud)
我的计划是更改上述代码中的URL以指向的地址WebAPI 2
,但在身份验证期间失败。 如果我在内的Controller上删除了[Authorize]类属性WebAPI 2
,它确实成功建立了连接并返回了预期的数据,但是启用该属性后,它甚至没有在Controller上遇到断点,这向我暗示了问题所在与我要使用的承载令牌在一起,或者 WebAPI 2配置不正确。
获取安全令牌的副本并尝试再次使用此过程也无法正常工作,因为我认为该令牌用于WebAPI 1
,因此对于与无效WebAPI 2
。
我应该像这样进行通过验证吗?(WebAPI 1
将可以访问的用户凭据硬编码到其中感觉很脏WebAPI 2
,所以我不想这样做。此外,如果需要更改用户凭据,我只是为此而进行了重新部署。)
有没有更好的方法来做我想做的事情?
如果您需要我提供更多信息来解释我所做的任何事情,我当然可以做到。
更新1:这是Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
services.AddProtectWebApiWithMicrosoftIdentityPlatformV2(Configuration)
.AddProtectedApiCallsWebApis(Configuration, new string[] { "user.read", "offline_access" })
.AddInMemoryTokenCaches();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
...
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseMvc();
}
Run Code Online (Sandbox Code Playgroud)
更新2:类似的堆栈溢出文章我已经找到了这个SO文章,@ philippe-signoret在他的回答中描述了,这正是我所追求的。
更新3:呼叫时未经授权的响应WebAPI 2
这是我从电话中得到的错误消息:
{StatusCode: 401, ReasonPhrase: 'Unauthorized', Version: 1.1, Content: System.Net.Http.HttpConnection+HttpConnectionResponseContent, Headers:
{
Server: Kestrel
WWW-Authenticate: Bearer error="invalid_token", error_description="The signature is invalid"
X-SourceFiles: =?UTF-8?B?*<random-looking-code>*
X-Powered-By: ASP.NET
Date: Fri, 31 May 2019 09:48:31 GMT
Content-Length: 0
}}
Run Code Online (Sandbox Code Playgroud)
如前所述,如果从控制器的类中删除[Authorize]属性,则调用将按预期进行。
小智 0
您应该参考的示例是https://github.com/Azure-Samples/active-directory-dotnet-webapp-webapi-openidconnect-aspnetcore。此示例包含在受 Azure AD 保护的 ASP.NET Core 2.0 上运行的 Web API。Web API 由 ASP.NET Core 2.0 Web 应用程序代表登录用户进行访问。
示例中的中间应用程序是Web应用程序,而不是Web api,但底层原理是相同的。
我建议您首先严格遵循此示例,以便了解如何代表用户从 Web api 1 调用 Web api 2。请注意“注册 TodoListWebApp Web 应用程序”部分下的步骤 6、7 :
6, From the Settings blade, select Required permissions. Select + Add, and then select Select an API.
Type TodoListService in the textbox and press Enter. Select the web API from the list and then select the Select button. Select Select Permissions.
Tick the checkbox next to Access TodoListService and then select the Select button. Select the Done button.
7, In the Settings blade, under API Access, select Required permissions.
Click on the Grant Permissions and when prompted press Yes.
Once the web app is granted access to the webapi you should see the following message: Successfully granted permissions to the application for your account.
To grant permissions for all users, please have an admin consent to the application.
Run Code Online (Sandbox Code Playgroud)
在Web应用程序中调用Web api的核心代码片段如下:
// Because we signed-in already in the WebApp, the userObjectId is know
string userObjectID = (User.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier"))?.Value;
// Using ADAL.Net, get a bearer token to access the TodoListService
AuthenticationContext authContext = new AuthenticationContext(AzureAdOptions.Settings.Authority, new NaiveSessionCache(userObjectID, HttpContext.Session));
ClientCredential credential = new ClientCredential(AzureAdOptions.Settings.ClientId, AzureAdOptions.Settings.ClientSecret);
result = await authContext.AcquireTokenSilentAsync(AzureAdOptions.Settings.TodoListResourceId, credential, new UserIdentifier(userObjectID, UserIdentifierType.UniqueId));
// Retrieve the user's To Do List.
HttpClient client = new HttpClient();
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, AzureAdOptions.Settings.TodoListBaseAddress + "/api/todolist");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);
HttpResponseMessage response = await client.SendAsync(request);
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1579 次 |
最近记录: |