具有IS4的Azure.Net核心应用程序:Web API调用失败,并显示"持有者错误=INVALID_TOKEN颁发者无效&Quot; [英] azure .net core app with IS4: web api call fails with "Bearer error=invalid_token The issuer is invalid"

查看:0
本文介绍了具有IS4的Azure.Net核心应用程序:Web API调用失败,并显示"持有者错误=INVALID_TOKEN颁发者无效&Quot;的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个.Net Core 3.1应用在Azure Web App for Containers(Linux)服务中运行。此应用程序是一个Web API项目,前端为角9。它使用Identity Server 4进行授权。

作为参考,我将此clean architecture framework template用于我的项目(Add Docker Support PR)。

该应用程序在该服务中运行良好。前端工作正常,我可以使用ID4登录,我可以看到登录时返回了授权令牌。

问题:

当我从前端角度客户端应用程序调用后端Web API时,收到以下错误:

HTTP/1.1 401 Unauthorized
Server: Kestrel
WWW-Authenticate: Bearer error="invalid_token", error_description="The issuer 'https://*********.azurewebsites.net' is invalid"

我很想为IssuerUri添加手动设置,但identity server 4 docs建议不要这样做,因此我没有这样做。也许在码头上运行会让情况有所不同。

根据these docs for proxy load balancers.我必须在我的应用程序设置中添加ASPNETCORE_FORWARDEDHEADERS_ENABLED=TRUE

,我必须添加对转发标头的支持才能使IS4正常工作

当我比较请求的.AspNetCore.Identity.Application结果时,我可以看到AspNetCore.Antiforgery对于登录和Web API调用是相同的,但fiddler值不同。

我正在使用NSWAG自动生成角度的API服务调用,如果这有什么不同的话。

问题:

有人能帮我找出为什么我可以登录,但所有Web API请求都失败,并出现上面的未授权错误吗?

提前谢谢。 JK

编辑%1

我使用fiddler获取请求的授权令牌,并使用jwt.io对其进行解析。ISS值与应用程序/Web API相同:

"iss": "https://******.azurewebsites.net", 

IS4使用此域登录,并正常工作。如果该值正确,是否还有其他可能出错的地方?

编辑2:

仅查看更多上下文。

我的应用在statup.cs中使用配置

app.UseHsts();
app.UseHttpsRedirection();

因此,我需要添加以下代码,以确保在应用程序服务处理TSL、负载均衡器/代理和我的docker容器(starup.cs ConfigureServices)之间的请求中转发Header:

// the following is documented here:
// https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer?view=aspnetcore-2.1#forward-the-scheme-for-linux-and-non-iis-reverse-proxies-1
// it is needed to run kestrel in azure app service in http with header forwarding
if (string.Equals(
    Environment.GetEnvironmentVariable("ASPNETCORE_FORWARDEDHEADERS_ENABLED"),
    "true", StringComparison.OrdinalIgnoreCase))
{
    services.Configure<ForwardedHeadersOptions>(options =>
    {
        options.ForwardedHeaders = ForwardedHeaders.XForwardedFor |
                                   ForwardedHeaders.XForwardedProto;
        // Only loopback proxies are allowed by default.
        // Clear that restriction because forwarders are enabled by explicit 
        // configuration.
        options.KnownNetworks.Clear();
        options.KnownProxies.Clear();
    });
}

我在日志中看到以下错误,这些错误将上面的错误确认为发行者不匹配

Microsoft.IdentityModel.Tokens.SecurityTokenInvalidIssuerException: IDX10205:颁发者验证失败。发行者:‘[PII是隐藏的。了解更多 详情,请参阅https://aka.ms/IdentityModel/PII.]‘.不匹配: Validation参数。ValidIssuer...

我正在使用以下JWT令牌的默认设置:

 services.AddAuthentication().AddIdentityServerJwt();

如果我导航到https://*******.azurewebsites.net/.well-known/openid-configuration/jwks,我会得到以下OIDC设置的JSON设置:

{
  "issuer": "https://*******.azurewebsites.net",
  "jwks_uri": "https://*******.azurewebsites.net/.well-known/openid-configuration/jwks",
  "authorization_endpoint": "https://*******.azurewebsites.net/connect/authorize",
  "token_endpoint": "https://*******.azurewebsites.net/connect/token",
  "userinfo_endpoint": "https://*******.azurewebsites.net/connect/userinfo",
  "end_session_endpoint": "https://*******.azurewebsites.net/connect/endsession",
  "check_session_iframe": "https://*******.azurewebsites.net/connect/checksession",
  "revocation_endpoint": "https://*******.azurewebsites.net/connect/revocation",
  "introspection_endpoint": "https://*******.azurewebsites.net/connect/introspect",
  "device_authorization_endpoint": "https://*******.azurewebsites.net/connect/deviceauthorization",
  "frontchannel_logout_supported": true,
  "frontchannel_logout_session_supported": true,
  "backchannel_logout_supported": true,
  "backchannel_logout_session_supported": true,
  "scopes_supported": [
    "openid",
    "profile",
    "CleanArchitecture.WebUIAPI",
    "offline_access"
  ],
  "claims_supported": [
    "sub",
    "name",
    ....
    "updated_at"
  ],
  "grant_types_supported": [
    "authorization_code",
    "client_credentials",
    "refresh_token",
    "implicit",
    "password",
    "urn:ietf:params:oauth:grant-type:device_code"
  ],
  "response_types_supported": [
    "code",
    "token",
    "id_token",
    "id_token token",
    "code id_token",
    "code token",
    "code id_token token"
  ],
  "response_modes_supported": ["form_post", "query", "fragment"],
  "token_endpoint_auth_methods_supported": [
    "client_secret_basic",
    "client_secret_post"
  ],
  "id_token_signing_alg_values_supported": ["RS256"],
  "subject_types_supported": ["public"],
  "code_challenge_methods_supported": ["plain", "S256"],
  "request_parameter_supported": true
}

我比较了本文档中的颁发者,它们与上面解码的令牌中的颁发者相同。

我仍然不确定如何对其进行调试以找出发行人不匹配的位置。

注意:我已将范围缩小了一点。对内置/默认IS4端点的所有呼叫均可正常工作。这是我在控制器中定义的唯一没有正确验证令牌的自定义WebAPI终结点。

任何具有[Authorize]属性的WebAPI终结点都失败,颁发者无效

编辑3:

感谢@d_f评论,我将IS4文档用于adding local API 我在启动.ca配置服务中添加了以下对我的服务初始化的调用:

services.AddIdentityServer().AddApiAuthorization<ApplicationUser, ApplicationDbContext>();
services.AddLocalApiAuthentication();  // I added this line after the above line

然后我将我的webAPI控制器顶部的[授权]属性更改为:

//[Authorize]
[Authorize(IdentityServerConstants.LocalApi.PolicyName)]
但是,我仍然收到相同的错误。只有在我定制的webAPI端点上,IS4端点才能正常工作。登录可用,但不能用于任何具有[Authorize]属性的Web API终结点。

编辑4:

我删除了上面的设置并更改了我的服务。将AUTHENTATION()添加到以下项:

services.AddAuthentication()
    .AddIdentityServerJwt()
    .AddLocalApi(options =>
        options.ExpectedScope = "IdentityServer4");

我也试过了:

services.AddAuthentication()
    .AddIdentityServerJwt()
    .AddLocalApi();

我使用策略名称";IdentityServer4";是因为它似乎是IS4中的默认策略

以下是完整的上下文:

services.AddDefaultIdentity<ApplicationUser>()
    .AddEntityFrameworkStores<ApplicationDbContext>();

services.AddIdentityServer()
    .AddApiAuthorization<ApplicationUser, ApplicationDbContext>();

services.AddAuthentication()
    .AddIdentityServerJwt() 
    .AddLocalApi(options =>
        options.ExpectedScope = "IdentityServer4");

这在我的机器上使用所有这些变体在本地工作。仅当在Azure Web应用程序的容器内运行时,我的自定义WebAPI终结点才会出现颁发者故障。

解决方案:

多亏了这里所有的帮助,我找到了一个解决方案。IS4开箱即用尝试自动设置ISS/颁发者。这在本地运行,但在我的生产环境中,我的容器运行在用于容器的azure web应用程序中。Azure将我的容器放在另一个容器中,以实现负载平衡/代理来处理HTTPS加密。因此,在我的容器中自动检测到的IS4颁发者与Azure Web应用程序URL之间存在差异。

通过在我的代码中手动设置颁发者,错误消失,一切正常。

您可以在两个地方执行此操作

  1. 在您的appsettings.jsson中:
     "IdentityServer": {
        "IssuerUri": "https://yourapp.azurewebsites.net", 
  1. 或使用如下代码:
      services.AddIdentityServer(options =>
                {
                    options.IssuerUri = "https://your.azurewebsites.net/";
                })
                .AddApiAuthorization<ApplicationUser, ApplicationDbContext>();

希望这对其他人有所帮助,并再次感谢所有帮助过这里的人

推荐答案

解决方案:

多亏了这里所有的帮助,我找到了一个解决方案。IS4开箱即用尝试自动设置ISS/颁发者。这在本地运行,但在我的生产环境中,我的容器运行在用于容器的azure web应用程序中。Azure将我的容器放在另一个容器中,以实现负载平衡/代理来处理HTTPS加密。因此,在我的容器中自动检测到的IS4颁发者与Azure Web应用程序URL之间存在差异。

通过在我的代码中手动设置颁发者,错误消失,一切正常。

您可以在两个地方执行此操作

  1. 在您的appsettings.jsson中:
     "IdentityServer": {
        "IssuerUri": "https://yourapp.azurewebsites.net", 
  1. 或使用如下代码:
      services.AddIdentityServer(options =>
                {
                    options.IssuerUri = "https://your.azurewebsites.net/";
                })
                .AddApiAuthorization<ApplicationUser, ApplicationDbContext>();

希望这对其他人有所帮助,并再次感谢所有帮助过这里的人

这篇关于具有IS4的Azure.Net核心应用程序:Web API调用失败,并显示&quot;持有者错误=INVALID_TOKEN颁发者无效&Quot;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆