C# API可以';在未将context.Request.Scheme设置为“0”的情况下,无法连接到Azure上的IdentityServer 4;https";

C# API可以';在未将context.Request.Scheme设置为“0”的情况下,无法连接到Azure上的IdentityServer 4;https";,c#,asp.net-core,.net-core,identityserver4,C#,Asp.net Core,.net Core,Identityserver4,我有两个服务,API和IdentityService4,托管在Azure上,带有Kubernetes(Azure Kubernetes服务) 当我通过VisualStudio运行服务时,一切正常,IS4正确验证令牌。 但是,当我尝试调用任何需要授权的“生产”请求时,我会遇到以下异常: System.InvalidOperationException: IDX20803: Unable to obtain configuration from: 'System.String'. --->

我有两个服务,API和IdentityService4,托管在Azure上,带有Kubernetes(Azure Kubernetes服务)

当我通过VisualStudio运行服务时,一切正常,IS4正确验证令牌。 但是,当我尝试调用任何需要授权的“生产”请求时,我会遇到以下异常:

System.InvalidOperationException: IDX20803: Unable to obtain configuration from: 'System.String'.
 ---> System.ArgumentException: IDX20108: The address specified 'System.String' is not valid as per HTTPS scheme. Please specify an https address for security reasons. If you want to test with http address, set the RequireHttps property  on IDocumentRetriever to false. (Parameter 'address')
   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)
我发现了这个问题:并使用了这个解决方案:

app.Use((context,next)=>{context.Request.Scheme=“https”;return-next();})

但我不确定这是否是一个“安全”的解决方案,因为它似乎有点黑客

API配置

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();
    services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(options =>
            {
                options.Authority = "https://mylinkttoIS4.com";
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateAudience = false
                };
            });
    services.AddAuthorization();
    services.AddHttpContextAccessor();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.Use((context, next) => { context.Request.Scheme = "https"; return next(); });
    app.UseHttpsRedirection();
    app.UseRouting();
    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers().RequireAuthorization();
    });
}
IdentityServer4配置

public void ConfigureServices(IServiceCollection services)
{
    var databaseConnectionString = Configuration.GetConnectionString("DefaultConnection");

    services.AddDbContext<DatabaseContext>(options => options.UseSqlServer(databaseConnectionString));

    services.AddIdentity<User, IdentityRole<Guid>>().AddEntityFrameworkStores<DatabaseContext>()
      .AddDefaultTokenProviders();

    services.AddIdentityServer()
            .AddSigningCredentialBasedOnEnvironment(Configuration, Environment)
            .AddInMemoryApiScopes(IdentityServerConfig.ApiScopes)
            .AddInMemoryClients(IdentityServerConfig.Clients)
            .AddAspNetIdentity<User>()
            .AddOperationalStore(options =>
            {
                options.ConfigureDbContext = builder => builder.UseSqlServer(databaseConnectionString, sql => sql.MigrationsAssembly(typeof(Startup).GetTypeInfo().Assembly.GetName().Name));
                options.DefaultSchema = "identity";
            })
            .AddResourceOwnerValidator<CustomResourceOwnerPasswordValidator>();

    services.AddTransient<ISmsSender, SmsSender>();
}

public void Configure(IApplicationBuilder app)
{
    app.UseHttpsRedirection();
    app.UseIdentityServer();
}
public void配置服务(IServiceCollection服务)
{
var-databaseConnectionString=Configuration.GetConnectionString(“DefaultConnection”);
services.AddDbContext(options=>options.UseSqlServer(databaseConnectionString));
services.AddIdentity().AddEntityFrameworkStores()
.AddDefaultTokenProviders();
services.AddIdentityServer()
.AddSigningCredentialBasedOnEnvironment(配置、环境)
.AddInMemoryApiScopes(IdentityServerConfig.ApiScopes)
.AddInMemoryClients(IdentityServerConfig.Clients)
.AddAsNetIdentity()
.addStore(选项=>
{
options.ConfigureDbContext=builder=>builder.UseSqlServer(databaseConnectionString,sql=>sql.MigrationAssembly(typeof(Startup).GetTypeInfo().Assembly.GetName().Name));
options.DefaultSchema=“identity”;
})
.AddResourceOwnerValidator();
services.AddTransient();
}
公共void配置(IApplicationBuilder应用程序)
{
app.UseHttpsRedirection();
app.UseIdentityServer();
}
你知道这条线在干什么吗? 在生产环境中使用是否安全?
可能是Azure配置的问题?

这取决于您在哪里终止HTTPS,在Kestrel或Azure中。。。Azure中的许多服务将在您的应用程序外部终止HTTPS,然后将流量作为HTTP发送到您的服务

{internet}->HTTPS->{Azure负载平衡器/网关…}->HTTP->{您的应用程序}


也可能是由于网络配置的原因,客户端无法访问IdentityServer。

您没有按照错误消息中的建议执行操作的原因是什么
如果要使用http地址进行测试,请将IDocumentRetriever上的RequireHttps属性设置为false。
但我希望所有流量都是https。我猜TLS/SSL将在负载平衡器处终止,并且您通过http接收到的流量没有相应的
x-forwarded-proto
头,或者标头不受信任。如果是这种情况,您需要适当地配置应用程序以信任标头,以便应用程序确定方案为HTTPS:我将使用转发标头,谢谢。我已确认HTTPS已终止,谢谢。