azure.net核心应用程序与IS4:web api调用失败,返回“0”;承载错误=无效“发卡机构无效”;

azure.net核心应用程序与IS4:web api调用失败,返回“0”;承载错误=无效“发卡机构无效”;,azure,docker,azure-web-app-service,identityserver4,nswag,Azure,Docker,Azure Web App Service,Identityserver4,Nswag,我有一个运行在azure web app for containers(linux)服务中的.net Core 3.1应用程序。此应用程序是一个web api项目,具有角度9前端。它使用身份服务器4进行授权 作为参考,我使用我的项目(添加docker支持公关) 该应用程序在服务中运行良好。前端工作,我可以使用ID4“登录”,并且我可以看到在登录时返回授权令牌 问题是: 从前端angular客户端应用程序调用后端web api时,出现以下错误: HTTP/1.1 401 Unauthorized

我有一个运行在azure web app for containers(linux)服务中的.net Core 3.1应用程序。此应用程序是一个web api项目,具有角度9前端。它使用身份服务器4进行授权

作为参考,我使用我的项目(添加docker支持公关)

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

问题是: 从前端angular客户端应用程序调用后端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添加手动设置,但建议不要这样做,因此我没有这样做。也许在docker中运行会使情况有所不同

我必须添加对转发头的支持,才能使IS4在startup.cs configureServices中正常工作,根据我必须将ASPNETCORE_FORWARDEDHEADERS_ENABLED=true添加到我的应用程序设置中

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

我正在使用nSwag为angular自动生成api服务调用,如果这会产生影响的话

问题: 有人能帮我弄清楚为什么我可以登录,但所有的web api请求都会因上述未经授权的错误而失败吗

提前谢谢。 JK

编辑1 我使用fiddler获取请求的授权令牌,并使用jwt.io解析它。iss值与app/web api相同:

"iss": "https://******.azurewebsites.net", 
IS4使用此域登录,并且工作正常。如果该值是正确的,是否还有其他错误

编辑2: 只是为了了解更多情况

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

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

如果我导航到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文档 我在startu.ca configure services中为我的服务初始化添加了以下调用:

services.AddIdentityServer().AddApiAuthorization<ApplicationUser, ApplicationDbContext>();
services.AddLocalApiAuthentication();  // I added this line after the above line
然而,我仍然得到同样的错误。只有在我的自定义webAPI端点上,IS4端点才能正常工作。登录可以工作,但没有任何具有[Authorize]属性的web api端点

编辑4: 我删除了上述设置,并将我的services.AddAUthentication()更改为以下内容:

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");
  • 或者用这样的代码:
  • services.AddIdentityServer(选项=>
    {
    options.IssuerUri=”https://your.azurewebsites.net/";
    })
    .addapi授权();
    

    希望这对其他人有所帮助,并再次感谢所有在此提供帮助的人

    您需要捕获您的令牌并使用它进行解析

    根据您的错误消息:
    invalid token发卡机构无效
    ,因此您应该检查令牌中的
    iss
    声明,以确保其与发卡机构匹配的API中的预期一致。看

    解决方案: 多亏了这里的帮助,我找到了解决办法。IS4开箱即用尝试自动设置ISS/Issuer。这在本地工作,但在我的生产环境中,我的容器在azure web apps for containers中运行。Azure将我的容器放在另一个容器中,用于负载平衡/代理以处理https加密。因此,在我的容器中自动检测到的IS4颁发者与azure web app URL之间存在差异

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

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

  • 在appsettings.jsson中,您可以选择:
  • 或者用这样的代码:
  • services.AddIdentityServer(选项=>
    {
    options.IssuerUri=”https://your.azurewebsites.net/";
    })
    .addapi授权();
    

    希望这对其他人有所帮助,并再次感谢所有在此提供帮助的人

    访问令牌中的颁发者是什么?它是否与API中预期的颁发者匹配?我如何确定?将请求传递到identity server或通过一些代理(如Fiddler)传递到API。我忽略了使用“一体式”模板的要点,假设您的identity server单独托管。对于多功能一体机,您可以尝试切换到
    services.AddAuthentication().AddLocalApi(“token”,isAuth=>{/*在此处自定义验证*/})@d\f感谢您的持续帮助。我很难找到AddLocalApi()的示例。我添加了Edit#4以显示我尝试使用它的两种方式。您好,我检查了授权令牌,它显示“iss”:“https://********.azurewebsites.net”,这是我在azure中运行的应用程序。IS4服务器也在该域上运行。我在ssl设置方面遇到了一些问题,是否可能
    
    services.AddAuthentication()
        .AddIdentityServerJwt()
        .AddLocalApi(options =>
            options.ExpectedScope = "IdentityServer4");
    
    services.AddAuthentication()
        .AddIdentityServerJwt()
        .AddLocalApi();
    
    services.AddDefaultIdentity<ApplicationUser>()
        .AddEntityFrameworkStores<ApplicationDbContext>();
    
    services.AddIdentityServer()
        .AddApiAuthorization<ApplicationUser, ApplicationDbContext>();
    
    services.AddAuthentication()
        .AddIdentityServerJwt() 
        .AddLocalApi(options =>
            options.ExpectedScope = "IdentityServer4");
    
         "IdentityServer": {
            "IssuerUri": "https://yourapp.azurewebsites.net", 
    
          services.AddIdentityServer(options =>
                    {
                        options.IssuerUri = "https://your.azurewebsites.net/";
                    })
                    .AddApiAuthorization<ApplicationUser, ApplicationDbContext>();
    
         "IdentityServer": {
            "IssuerUri": "https://yourapp.azurewebsites.net", 
    
          services.AddIdentityServer(options =>
                    {
                        options.IssuerUri = "https://your.azurewebsites.net/";
                    })
                    .AddApiAuthorization<ApplicationUser, ApplicationDbContext>();