为 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的主要内容,如果未能解决你的问题,请参考以下文章