Degusto
Degusto

Reputation: 291

API can't connect to IdentityServer4 on Azure without context.Request.Scheme set to "https"

I have two services, API and IdentityService4 hosted on Azure with Kubernetes(Azure Kubernetes Service).

When I run services via Visual Studio everything works and IS4 correctly validates tokens. However when I try to invoke any request on "production" that requires authorization I get following exception:

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)

I have found this issue: https://github.com/IdentityServer/IdentityServer4/issues/4645 and used this solution:

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

But I'm not sure if this is a "safe" solution because it seems a little hackish.

API config

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 config

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();
}

Do you know what this line is doing? Is it safe to use in production environment? Maybe it's something with Azure configuration?

Upvotes: 3

Views: 609

Answers (1)

Tore Nestenius
Tore Nestenius

Reputation: 19921

It depends on where you terminate HTTPS, in Kestrel or in Azure... Many services in Azure will terminate HTTPS outside your application and then send the traffic to your service as HTTP.

{internet} -> HTTPS -> {Azure Load Balancer/gateway...} -> HTTP -> {Your application}

Can also be that the client can't reach IdentityServer due to network configuration.

Upvotes: 1

Related Questions