为 HTTPS 配置 ASP.NET Core 2.0 Kestrel

Posted

技术标签:

【中文标题】为 HTTPS 配置 ASP.NET Core 2.0 Kestrel【英文标题】:Configure ASP.NET Core 2.0 Kestrel for HTTPS 【发布时间】:2018-03-02 08:35:47 【问题描述】:

TL;DR 现在使用 ASP.NET Core 2.0 设置 HTTPS 的正确方法是什么?

我想将我的项目配置为使用 https 和他们在BUILD 2017 中显示的证书。我尝试了几种设置,但没有任何效果。经过一番研究,我更加困惑。看来配置url和port的方法有很多……我见过appsettings.jsonhosting.json,通过代码,在launchsettings.json中我们也可以设置url和port。

有没有“标准”的方式来做到这一点?

这是我的appsettings.development.json


  "Kestrel": 
    "Endpoints": 
      "Localhost": 
        "Address": "127.0.0.1",
        "Port": "40000"
      ,
      "LocalhostWithHttps": 
        "Address": "127.0.0.1",
        "Port": "40001",
        "Certificate": 
          "HTTPS": 
            "Source": "Store",
            "StoreLocation": "LocalMachine",
            "StoreName": "My",
            "Subject": "CN=localhost",
            "AllowInvalid": true
          
        
      
    
  

但是当我从命令行使用dotnet run 启动或从Visual Studio 启动调试器时,它总是从launchsettings.json 获取url 和端口。

这是我的Program.csStartup.cs

public class Program

    public static void Main(string[] args)
    
        BuildWebHost(args).Run();
    

    public static IWebHost BuildWebHost(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>()
            .Build();


public class Startup

    public IConfiguration Configuration  get; 
    public string Authority  get; set;  = "Authority";
    public string ClientId  get; set;  = "ClientId";

    public Startup(IConfiguration configuration)
    
        Configuration = configuration;
    

    public void ConfigureServices(IServiceCollection services)
    
        services.Configure<MvcOptions>(options => options.Filters.Add(new RequireHttpsAttribute()));

        JsonConvert.DefaultSettings = () => new JsonSerializerSettings() 
            NullValueHandling = NullValueHandling.Ignore
        ;

        services.AddSingleton<IRepository, AzureSqlRepository>(x => new AzureSqlRepository(Configuration.GetConnectionString("DefaultConnection")));
        services.AddSingleton<ISearchSplitService, SearchSplitService>();

        services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(options => new JwtBearerOptions 
                Authority = this.Authority,
                Audience = this.ClientId
        );

        services.AddMvc();
    

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    
        if (env.IsDevelopment())
        
            app.UseDeveloperExceptionPage();
            app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions()  HotModuleReplacement = true, ReactHotModuleReplacement = true, HotModuleReplacementEndpoint = "/dist/__webpack_hmr" );
        

        app.UseStaticFiles();
        app.UseAuthentication();

        app.UseMvc(routes => 
            routes.MapRoute(
                name: "default",
                template: "controller=Home/id?");

            routes.MapSpaFallbackRoute(
                name: "spa-fallback",
                defaults: new  controller = "Home", action = "Index" );
        );
    

正如我所说,我无法让它在任何情况下工作。今天使用 ASP.NET Core 2.0 设置 HTTPS 的正确方法是什么?

【问题讨论】:

在生产中,最好使用 nginx 作为前端,使用 nginx 配置 SSL/TLS 很简单,你可以保持 kestrel 服务于 http。众所周知的做法是为后端进行 ssl-offloading,以避免不必要的复杂性和性能降低,而不会影响安全。 MS Azure 应用了类似的架构概念。 【参考方案1】:

很遗憾,在 ASP.NET Core 2.0 发布之前,各种视频或教程中已经展示了基于配置的 HTTPS 设置方式,但并未进入最终版本。

对于 2.0,配置 HTTPS 的唯一方法是在代码中,通过显式设置 Kestrel 侦听器,如 in this announcement 所述,并使用 ListenOptions.UseHttps 启用 HTTPS:

var host = new WebHostBuilder()
    .UseKestrel(options =>
    
        options.ListenAnyIP(443, listenOptions => 
        
            listenOptions.UseHttps("server.pfx", "password");
        );
    )
    .UseStartup<Startup>()
    .Build();

不幸的是,在发布时,官方文档没有正确涵盖这一点,并宣传了未实现的基于配置的方式。 This has been fixed since.

从 ASP.NET Core 2.1 开始,基于配置的 HTTPS 设置将成为可能,正如最初承诺的那样。正如Tratcher on GitHub 所解释的那样,这可能看起来像这样:

"Kestrel": 
  "Endpoints": 
    "HTTPS": 
      "Url": "https://*:443",
      "Certificate": 
        "Path": "server.pfx",
        "Password": "password"
      
    
  


在您的特定示例中,基于代码的配置如下所示。请注意,如果您不想使用 证书文件,则需要先手动从证书存储中检索证书。

.UseKestrel(options =>

    // listen for HTTP
    options.ListenLocalhost(40000);

    // retrieve certificate from store
    using (var store = new X509Store(StoreName.My))
    
        store.Open(OpenFlags.ReadOnly);
        var certs = store.Certificates.Find(X509FindType.FindBySubjectName, 
            "localhost", false);
        if (certs.Count > 0)
        
            var certificate = certs[0];

            // listen for HTTPS
            options.ListenLocalhost(40001, listenOptions =>
            
                listenOptions.UseHttps(certificate);
            );
        
    
)

【讨论】:

谢谢,现在我知道我为什么这么困惑了...您能否在示例中添加一些代码,以反映我在 appsettings.json 中为 https 所做的设置?我真的很感激。 添加(未经测试)的代码应该与您的配置匹配。 我们今天在哪里。是否有与 Kestrel 的 netsh http add sslcert 命令等效的命令?它目前默认为我机器商店中的“localhost”证书,因此必须有一种方法可以更改默认指纹。 @DonaldAirey 您可以使用我上面描述的带有appsettings.json 的配置来显式配置证书。你不需要使用netsh,因为你不是通过 HTTPsys 托管的(所以 netsh 没有效果)。

以上是关于为 HTTPS 配置 ASP.NET Core 2.0 Kestrel的主要内容,如果未能解决你的问题,请参考以下文章

.NET 6学习笔记——ASP.NET Core通过配置文件启用HTTPS

无法使用 HTTPS 启动 ASP.NET Core

Asp.net core HttpsRedirectionMiddleware 无法确定重定向的 https 端口

ASP.NET Core 1.0 Configuration 配置管理

ASP.NET Core 2 中的问题配置选项

asp.net core序列化json配置,适用于mvc,webapi