Azure App Services 在访问需要身份验证的 Web api 终结点时获取 401。但在本地工作

Azure App Services Getting 401 when accessing an web api endpoint that requires authentication. But works locally

我在 Azure 应用服务中使用 angular 7 作为前端和后端网络核心 Web api。

当我调用需要身份验证的端点时,它在本地工作,但是当它通过 devops 部署在 Azure 上时,只有 public 端点工作,而不是需要身份验证的端点。

这是我在控制台浏览器中收到的错误消息 https://mysite.azurewebsites.net/api/test/private 的 HTTP 失败响应:401 未经授权

我的 Angular web api 对 Azure 后端的调用

  public questsRead(quest_Id:string): Observable<IQuest_vmr>{

    const apiUrlPath = this.baseUrlBackend+'api/Quest/QuestRead';

    const obser = this.httpClient.get(apiUrlPath, {
      headers: new HttpHeaders().set('Authorization', `Bearer ${this.auth0IdToken}`),
      params: {
        "quest_Id": quest_Id,
      },
      })
      .map((response: IQuest_vmr) => response);

    return obser;
  }

这是我的网络 api 应用程序中 运行 auth0 服务

的启动
    public static void ConfigureServices(IServiceCollection services, IConfiguration Configuration)
    {

        string auth0_Config_Domain = Configuration["Auth0:Domain"];
        services.AddAuthentication(options =>
        {
            options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;


        }).AddJwtBearer(options =>
        {


            options.Authority = auth0_Config_Domain;
            options.Audience = Configuration["Auth0:ApiIdentifier"];

            options.TokenValidationParameters = new TokenValidationParameters()
            {

                ValidAudience = Configuration["Auth0:ValidAudience"], 
                ValidIssuer = auth0_Config_Domain

            };
        });





        services.AddAuthorization(options =>
        {
            options.AddPolicy("read:messages", policy => policy.Requirements.Add(new HasScopeRequirement("read:messages", auth0_Config_Domain)));
        });


        // register the scope authorization handler
        services.AddSingleton<IAuthorizationHandler, HasScopeHandler>();



    }

从 Azure 登录

2019-12-18 20:16:33.702 +00:00 [Information] Microsoft.AspNetCore.Hosting.Internal.WebHost: Request starting HTTP/1.1 GET https://dev-naodca-backend-webapi.azurewebsites.net/api/test/private
2019-12-18 20:16:33.702 +00:00 [Trace] Microsoft.AspNetCore.HostFiltering.HostFilteringMiddleware: All hosts are allowed.
2019-12-18 20:16:33.702 +00:00 [Warning] Microsoft.AspNetCore.Cors.Infrastructure.CorsService: The CORS protocol does not allow specifying a wildcard (any) origin and credentials at the same time. Configure the policy by listing individual origins if credentials needs to be supported.
2019-12-18 20:16:33.702 +00:00 [Debug] Microsoft.AspNetCore.Cors.Infrastructure.CorsService: The request has an origin header: 'https://dev-naodca-ui-angular.azurewebsites.net'.
2019-12-18 20:16:33.702 +00:00 [Information] Microsoft.AspNetCore.Cors.Infrastructure.CorsService: CORS policy execution successful.
2019-12-18 20:16:33.702 +00:00 [Debug] Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler: AuthenticationScheme: Bearer was not authenticated.
2019-12-18 20:16:33.702 +00:00 [Trace] Microsoft.AspNetCore.HttpsPolicy.HstsMiddleware: Adding HSTS header to response.
2019-12-18 20:16:33.702 +00:00 [Debug] Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware: The request path /api/test/private does not match a supported file type
2019-12-18 20:16:33.702 +00:00 [Debug] Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware: The request path  does not match the path filter
2019-12-18 20:16:33.702 +00:00 [Debug] Microsoft.AspNetCore.Routing.Matching.DfaMatcher: 1 candidate(s) found for the request path '/api/test/private'
2019-12-18 20:16:33.702 +00:00 [Debug] Microsoft.AspNetCore.Routing.Matching.DfaMatcher: Endpoint 'WebApiNetCoreBaseProject.Controllers.Api.TestController.Private (WebApiNetCoreBaseProject)' with route pattern 'api/Test/private' is valid for the request path '/api/test/private'
2019-12-18 20:16:33.702 +00:00 [Debug] Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware: Request matched endpoint 'WebApiNetCoreBaseProject.Controllers.Api.TestController.Private (WebApiNetCoreBaseProject)'
2019-12-18 20:16:33.702 +00:00 [Information] Microsoft.AspNetCore.Routing.EndpointMiddleware: Executing endpoint 'WebApiNetCoreBaseProject.Controllers.Api.TestController.Private (WebApiNetCoreBaseProject)'
2019-12-18 20:16:33.702 +00:00 [Information] Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Route matched with {action = "Private", controller = "Test"}. Executing controller action with signature Microsoft.AspNetCore.Mvc.IActionResult Private() on controller WebApiNetCoreBaseProject.Controllers.Api.TestController (WebApiNetCoreBaseProject).
2019-12-18 20:16:33.702 +00:00 [Debug] Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Execution plan of authorization filters (in the following order): Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter
2019-12-18 20:16:33.702 +00:00 [Debug] Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Execution plan of resource filters (in the following order): Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.SaveTempDataFilter
2019-12-18 20:16:33.702 +00:00 [Debug] Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Execution plan of action filters (in the following order): Microsoft.AspNetCore.Mvc.ModelBinding.UnsupportedContentTypeFilter (Order: -3000), Microsoft.AspNetCore.Mvc.Infrastructure.ModelStateInvalidFilter (Order: -2000), WebApiNetCoreBaseProject.Configuration.Startup.Service_Authentication.CustomFilter_Authentication
2019-12-18 20:16:33.702 +00:00 [Debug] Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Execution plan of exception filters (in the following order): WebApiNetCoreBaseProject.Startup+MyExceptionFilter
2019-12-18 20:16:33.702 +00:00 [Debug] Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Execution plan of result filters (in the following order): Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.SaveTempDataFilter, Microsoft.AspNetCore.Mvc.Infrastructure.ClientErrorResultFilter (Order: -2000)
2019-12-18 20:16:33.702 +00:00 [Trace] Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Authorization Filter: Before executing OnAuthorizationAsync on filter Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter.
2019-12-18 20:16:33.702 +00:00 [Information] Microsoft.AspNetCore.Authorization.DefaultAuthorizationService: Authorization failed.
2019-12-18 20:16:33.702 +00:00 [Trace] Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Authorization Filter: After executing OnAuthorizationAsync on filter Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter.
2019-12-18 20:16:33.702 +00:00 [Information] Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'.
2019-12-18 20:16:33.702 +00:00 [Trace] Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Always Run Result Filter: Before executing OnResultExecuting on filter Microsoft.AspNetCore.Mvc.Infrastructure.ClientErrorResultFilter.
2019-12-18 20:16:33.702 +00:00 [Trace] Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Always Run Result Filter: After executing OnResultExecuting on filter Microsoft.AspNetCore.Mvc.Infrastructure.ClientErrorResultFilter.
2019-12-18 20:16:33.702 +00:00 [Trace] Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Before executing action result Microsoft.AspNetCore.Mvc.ChallengeResult.
2019-12-18 20:16:33.702 +00:00 [Information] Microsoft.AspNetCore.Mvc.ChallengeResult: Executing ChallengeResult with authentication schemes ().
2019-12-18 20:16:33.703 +00:00 [Information] Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler: AuthenticationScheme: Bearer was challenged.
2019-12-18 20:16:33.703 +00:00 [Trace] Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: After executing action result Microsoft.AspNetCore.Mvc.ChallengeResult.
2019-12-18 20:16:33.703 +00:00 [Trace] Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Always Run Result Filter: Before executing OnResultExecuted on filter Microsoft.AspNetCore.Mvc.Infrastructure.ClientErrorResultFilter.
2019-12-18 20:16:33.703 +00:00 [Trace] Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Always Run Result Filter: After executing OnResultExecuted on filter Microsoft.AspNetCore.Mvc.Infrastructure.ClientErrorResultFilter.
2019-12-18 20:16:33.703 +00:00 [Information] Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Executed action WebApiNetCoreBaseProject.Controllers.Api.TestController.Private (WebApiNetCoreBaseProject) in 0.4337ms
2019-12-18 20:16:33.703 +00:00 [Information] Microsoft.AspNetCore.Routing.EndpointMiddleware: Executed endpoint 'WebApiNetCoreBaseProject.Controllers.Api.TestController.Private (WebApiNetCoreBaseProject)'
2019-12-18 20:16:33.703 +00:00 [Information] Microsoft.AspNetCore.Hosting.Internal.WebHost: Request finished in 1.3235ms 401

从 fiddler 发现 Auth0 JWT 令牌是从 angular 发送到错误的受众的 wepapi。

HTTP/1.1 401 Unauthorized
Date: Fri, 20 Dec 2019 10:28:18 GMT
Server: Kestrel
Content-Length: 0
Vary: Origin
WWW-Authenticate: Bearer error="invalid_token", error_description="The audience is invalid"
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *

此外,angular html 拦截器并未在每次调用时为私人请求添加 JWT 令牌,因此我必须为该特定请求和所有其他请求手动添加它。