Openiddict-core: This server only accepts HTTPS requests.

Created on 10 Dec 2019  路  7Comments  路  Source: openiddict/openiddict-core

I'm using openiddict 2.0.1 with aspnet.core 2.0
This is my only option since paypal support for .net core is stopped at 2.0 so far.

So my problem is, for example: http://localhost:83917/connect/token will spit out access_token in a local environment, but when it's deployed to production in Azure, (https://api.blabla.com/connect/token) I get HTTPS error:

This server only accepts HTTPS requests.

Startup.cs published in production

  public class Startup
    {
        private readonly string _appSettingsEnv;

        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
            // Get value from Azure's App Settings when deployed. Debug (local) mode gets value from appsettings.json
            _appSettingsEnv = Configuration["APPSETTINGS:ENVIRONMENT"];
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            // Add database configurations  
            services.AddDbContext<PayPalContext>(options =>
            {               
                options.UseSqlServer(Configuration.GetConnectionString("DemoConnection"));
                options.UseOpenIddict();
            });

            // Add membership
            services.AddIdentity<ApplicationUser, IdentityRole>(options =>
            {
                // Password settings
                options.Password.RequireDigit = false;
                options.Password.RequireLowercase = false;
                options.Password.RequireNonAlphanumeric = false;
                options.Password.RequireUppercase = false;
                options.Password.RequiredLength = 5;
                options.User.RequireUniqueEmail = true;
                options.SignIn.RequireConfirmedEmail = false;
            })
                .AddEntityFrameworkStores<PayPalContext>()
                .AddDefaultTokenProviders();

            // Register the OAuth2 validation handler.
            services.AddAuthentication(o =>
            {
                o.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                o.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
                .AddJwtBearer(options =>
                {
                    options.Audience = "resource_server";
                    options.Authority = "https://api.blabla.com/";
                    options.RequireHttpsMetadata = true;
                    options.IncludeErrorDetails = true;
                    options.TokenValidationParameters = new TokenValidationParameters
                    {
                        NameClaimType = OpenIdConnectConstants.Claims.Subject,
                        RoleClaimType = OpenIdConnectConstants.Claims.Role
                    };
                });

            // Configure Identity to use the same JWT claims as OpenIddict instead
            // of the legacy WS-Federation claims it uses by default (ClaimTypes),
            // which saves you from doing the mapping in your authorization controller.
            services.Configure<IdentityOptions>(options =>
            {
                options.ClaimsIdentity.UserNameClaimType = OpenIdConnectConstants.Claims.Name;
                options.ClaimsIdentity.UserIdClaimType = OpenIdConnectConstants.Claims.Subject;
                options.ClaimsIdentity.RoleClaimType = OpenIdConnectConstants.Claims.Role;
            });

            services.AddOpenIddict()
               // Register the OpenIddict core services.
               .AddCore(options =>
               {
                   // Register the Entity Framework stores and models.
                   options.UseEntityFrameworkCore()
                         .UseDbContext<PayPalContext>();
               })
               // Register the OpenIddict server handler.
               .AddServer(options =>
               {               
                   options.UseMvc();
                   options.EnableTokenEndpoint("/connect/token");
                   options.AllowPasswordFlow();
                   options.AcceptAnonymousClients();
                   options.UseJsonWebTokens();
                   options.AddEphemeralSigningKey();
               });

            services.AddCors();
            services.AddMvc()
                .AddJsonOptions(opts =>
                {
                    // Force Camel Case to JSON
                    opts.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
                });

            // Without this controller actions are not forbidden if other roles are trying to access
            services.AddSingleton<IAuthenticationSchemeProvider, CustomAuthenticationSchemeProvider>();
            services.AddSingleton(Configuration);
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
            JwtSecurityTokenHandler.DefaultOutboundClaimTypeMap.Clear();

            app.UseStaticFiles();

            app.UseCors(builder =>
            {
                builder.AllowAnyOrigin();
                builder.AllowAnyHeader();
                builder.AllowAnyMethod();
                builder.AllowCredentials();
            });

            app.UseExceptionHandler(builder =>
            {
                builder.Run(async context =>
                {
                    context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
                    context.Response.Headers.Add("Access-Control-Allow-Origin", "*");

                    var error = context.Features.Get<IExceptionHandlerFeature>();
                    if (error != null)
                    {
                        //context.Response.AddApplicationError(error.Error.Message);
                        await context.Response.WriteAsync(error.Error.Message).ConfigureAwait(false);
                    }
                });
            });

            app.UseAuthentication();
            app.UseMvcWithDefaultRoute();
            app.UseWelcomePage();
        }
    }

Is there anything that I need to add in Startup.cs?

external question

All 7 comments

For some reasons, ASP.NET Core doesn't infer the correct scheme, that OpenIddict uses to determine whether the request uses transport security or not. Read https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer?view=aspnetcore-3.1 for options to mitigate that.

@PinpointTownes Thanks for the guidance. According to the article, I believe I need to use app.UseCertificateForwarding(); but this is not supported in .net core 2.0. Am I really the only person who's encountering this issue? people must have faced the similar issue before, but I can't find the resolution :(

No, that extension is for client certificates, it has nothing to do with server authentication. It's meant for people who use mutual or client authentication, you don't need it.

Ok. I think this can be related to TLS/SSL binding in my server app. I binded private certificate with a custom domain. (ex: api.blabla.com). What do you think?

I think https://github.com/aspnet/AspNetCore would be a more appropriate place for non-OpenIddict-specific questions 馃槃

Alright, so is it transport security related? I just wanna narrow it down so they can understand what I'm asking.

ASP.NET Core doesn't infer the correct scheme, that OpenIddict uses to determine whether the request uses transport security

Yes, it's a classical SSL/TLS issue.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jedielson picture jedielson  路  5Comments

prilutskiy picture prilutskiy  路  4Comments

Biarity picture Biarity  路  4Comments

slimwizard picture slimwizard  路  5Comments

jonathancod picture jonathancod  路  3Comments