所讨论的应用程序是这样设置的:有一个前端服务和一个后端服务。后端服务已在Azure AD中注册。前端服务使用已注册应用程序的clientId和tenantId通过Auth Code流接收JWT。然后,前端在每个请求的授权标头中传递此JWT。
下一步是让后端服务验证此令牌以提供对其端点的访问。那里有很多不同的示例,我发现很难确定使用什么。目前,我在Startup.cs中有此文件:
services.AddAuthentication(AzureADDefaults.BearerAuthenticationScheme)
.AddAzureADBearer(options => Configuration.Bind("AzureAd", options));
带有appsettings.json:
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "https://myapi.azurewebsites.net",
"TenantId": "xxxxx-xxxxxxxx.xxxxxxx.xxxxxx",
"IssuerId": "https://login.microsoftonline.com/xxxxxx-xxxxxx-xxxxx-xxxx",
"ClientId": "xxxx-xxxxxxxxx-xxxxxxxxx-xxxxxxxx"
}
当我尝试使用邮递员在标头中使用JWT调用端点时,出现以下错误:
System.InvalidOperationException: IDX20803: Unable to obtain configuration from: 'https://login.microsoftonline.com/{tenant}/.well-known/openid-configuration'.
---> System.IO.IOException: IDX20804: Unable to retrieve document from: 'https://login.microsoftonline.com/{tenant}/.well-known/openid-configuration'.
---> System.Net.Http.HttpRequestException: Resource temporarily unavailable
---> System.Net.Sockets.SocketException (11): Resource temporarily unavailable
at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean allowHttp2, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.GetHttpConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.DiagnosticsHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
at Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(String address, CancellationToken cancel)
--- End of inner exception stack trace ---
at Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(String address, CancellationToken cancel)
at Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfigurationRetriever.GetAsync(String address, IDocumentRetriever retriever, CancellationToken cancel)
at Microsoft.IdentityModel.Protocols.ConfigurationManager`1.GetConfigurationAsync(CancellationToken cancel)
--- End of inner exception stack trace ---
at Microsoft.IdentityModel.Protocols.ConfigurationManager`1.GetConfigurationAsync(CancellationToken cancel)
at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()
at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()
at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.AuthenticateAsync()
at Microsoft.AspNetCore.Authentication.AuthenticationService.AuthenticateAsync(HttpContext context, String scheme)
at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.AuthenticateAsync()
at Microsoft.AspNetCore.Authentication.AuthenticationService.AuthenticateAsync(HttpContext context, String scheme)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
我不知道这意味着什么或如何解决。一些网站建议指定metadataAdress,但它们没有告诉您要指定的内容或放置位置。是否有人对此错误有任何经验?
根据我的测试,如果要使用Azure AD保护Web api,请参考以下步骤
Register client application in Azure AD
a。注册申请
配置应用程序
a。 appsettings.json
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"TenantId": "<your azure ad tenant id>",
"Domain": "<your azure ad domain>",
"ClientId": "<you web api appid>"
},
b。在startup.cs
中添加以下代码。
ConfigureServices方法
public void ConfigureServices(IServiceCollection services)
{
var tenatId = Configuration["AzureAd:TenantId"];
services.AddAuthentication(AzureADDefaults.JwtBearerAuthenticationScheme)
.AddAzureADBearer(options => Configuration.Bind("AzureAd", options));
services.Configure<JwtBearerOptions>(AzureADDefaults.JwtBearerAuthenticationScheme, options =>
{
// This is a Microsoft identity platform web API.
options.Authority += "/v2.0";
options.TokenValidationParameters.ValidIssuers = new[] {
$"https://sts.windows.net/{tenatId}/",
$"https://login.microsoftonline.com/{tenatId}/v2.0"
};
// The web API accepts as audiences both the Client ID (options.Audience) and api://{ClientID}.
options.TokenValidationParameters.ValidAudiences = new[]
{
options.Audience,
$"api://{options.Audience}"
};
});
...
}
配置方法
...
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
...
Test