0

有问题的应用程序是这样设置的:有一个前端服务和一个后端服务。后端服务在 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)

我不知道这意味着什么或如何解决它。一些网站建议指定元数据地址,但他们没有告诉您指定什么或放在哪里。有没有人有这个错误的经验?

4

1 回答 1

1

根据我的测试,如果你想用 Azure AD 保护你的 web api,请参考以下步骤

  1. 在 Azure AD 中注册 Web api 应用程序

  2. 配置您的 api 范围 在此处输入图像描述

  3. 在 Azure AD 中注册客户端应用程序

    一个。注册申请

    湾。创建客户端密码 在此处输入图像描述

    C。配置 API 权限 在此处输入图像描述

  4. 配置应用程序

    一个。应用设置.json

    "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "TenantId": "<your azure ad tenant id>",
    "Domain": "<your azure ad domain>",
    "ClientId": "<you web api appid>"
    
    },
    

    湾。在startup.cs.

    • 配置服务方法

       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();
       ...
      
  5. 测试

在此处输入图像描述
在此处输入图像描述

于 2020-03-16T04:05:22.397 回答