.net 部署 多域名 https(ssl)通过代码方式_一事冇诚-编程思维

  在上一个文章中,传送门,给大家介绍了怎么在配置文件中使用 Kestrel 部署 Https,正好今天有小伙伴稳问到:可以通过代码的方式实现 Kestrel 的 Https 的部署吗?答案是肯定的,我们这次一样去不是多个域名。

  在使用代码实现中,我是主要使用到 ListenOptions.UseHttps,我们先看看官方文档怎么说吧,不想看我的可以直接跳转到官方文档,传送门


 

ListenOptions.UseHttps

将 Kestrel 配置为使用 HTTPS。

ListenOptions.UseHttps 扩展:

  • UseHttps:将 Kestrel 配置为使用 HTTPS,采用默认证书。 如果没有配置默认证书,则会引发异常。
  • UseHttps(string fileName)
  • UseHttps(string fileName, string password)
  • UseHttps(string fileName, string password, Action<HttpsConnectionAdapterOptions> configureOptions)
  • UseHttps(StoreName storeName, string subject)
  • UseHttps(StoreName storeName, string subject, bool allowInvalid)
  • UseHttps(StoreName storeName, string subject, bool allowInvalid, StoreLocation location)
  • UseHttps(StoreName storeName, string subject, bool allowInvalid, StoreLocation location, Action<HttpsConnectionAdapterOptions> configureOptions)
  • UseHttps(X509Certificate2 serverCertificate)
  • UseHttps(X509Certificate2 serverCertificate, Action<HttpsConnectionAdapterOptions> configureOptions)
  • UseHttps(Action<HttpsConnectionAdapterOptions> configureOptions)

ListenOptions.UseHttps 参数:

  • filename 是证书文件的路径和文件名,关联包含应用内容文件的目录。
  • password 是访问 X.509 证书数据所需的密码。
  • configureOptions 是配置 HttpsConnectionAdapterOptions 的 Action。 返回 ListenOptions
  • storeName 是从中加载证书的证书存储。
  • subject 是证书的主题名称。
  • allowInvalid 指示是否存在需要留意的无效证书,例如自签名证书。
  • location 是从中加载证书的存储位置。
  • serverCertificate 是 X.509 证书。

在生产中,必须显式配置 HTTPS。 至少必须提供默认证书。

下面要描述的支持的配置:

  • 无配置
  • 从配置中替换默认证书
  • 更改代码中的默认值

无配置

Kestrel 在 http://localhost:5000 和 https://localhost:5001 上进行侦听(如果默认证书可用)。

从配置中替换默认证书

Kestrel 可以使用默认 HTTPS 应用设置配置架构。 从磁盘上的文件或从证书存储中配置多个终结点,包括要使用的 URL 和证书。

架构的注意事项:

  • 终结点的名称不区分大小写。 例如,由于再也无法解析标识符“Families”,因此 HTTPS and Https 是等效的。
  • 每个终结点都要具备 Url 参数。 此参数的格式和顶层 Urls 配置参数一样,只不过它只能有单个值。
  • 这些终结点不会添加进顶层 Urls 配置中定义的终结点,而是替换它们。 通过 Listen 在代码中定义的终结点与在配置节中定义的终结点相累积。
  • Certificate 部分是可选的。 如果未指定 Certificate 部分,则使用 Certificates:Default 中定义的默认值。 如果没有可用的默认值,则使用开发证书。 如果没有默认值,且开发证书不存在,则服务器将引发异常,并且无法启动。
  • Certificate 部分支持多个证书源
  • 只要不会导致端口冲突,就能在配置中定义任何数量的终结点。

证书源

可以将证书节点配置为从多个源加载证书:

  • Path 和 Password 用于加载 .pfx 文件。
  • PathKeyPath 和 Password 用于加载 .pem/.crt 和 .key 文件。
  • Subject 和 Store 用于从证书存储中加载。

好了,罗嗦话说完了,我们抽取文档的一部分进行实践

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ListenAnyIP(5005, listenOptions =>
    {
        listenOptions.UseHttps(httpsOptions =>
        {
            var localhostCert = CertificateLoader.LoadFromStoreCert(
                "localhost", "My", StoreLocation.CurrentUser,
                allowInvalid: true);
            var exampleCert = CertificateLoader.LoadFromStoreCert(
                "example.com", "My", StoreLocation.CurrentUser,
                allowInvalid: true);
            var subExampleCert = CertificateLoader.LoadFromStoreCert(
                "sub.example.com", "My", StoreLocation.CurrentUser,
                allowInvalid: true);
            var certs = new Dictionary<string, X509Certificate2>(
                StringComparer.OrdinalIgnoreCase)
            {
                ["localhost"] = localhostCert,
                ["example.com"] = exampleCert,
                ["sub.example.com"] = subExampleCert
            };

            httpsOptions.ServerCertificateSelector = (connectionContext, name) =>
            {
                if (name is not null && certs.TryGetValue(name, out var cert))
                {
                    return cert;
                }

                return exampleCert;
            };
        });
    });
});

  上面的代码一看就能懂,比较无奈的是官方文档的 SSL 证书是从 证书存储区 里获取的,在实际应用中,明显是不够方便,最好是那种直接写 证书路径 和 密码的,这样才能一目了然嘛,而这里的关键就是 X509Certificate2 这个类了,可以看到,最终是通过检索一个字典返回的,接受的就是这个 X509Certificate2 类,所以我们看看这个类到底是个什么东西,传送门

  这里我们只关注构造函数,下面是官方文档,或者直接 F12 进去看更为直接


 

构造函数

X509Certificate2()
已过时。

初始化 X509Certificate2 类的新实例。

X509Certificate2(Byte[])

使用来自字节数组的信息初始化 X509Certificate2 类的新实例。

X509Certificate2(Byte[], SecureString)

使用一个字节数组和一个密码初始化 X509Certificate2 类的新实例。

X509Certificate2(Byte[], SecureString, X509KeyStorageFlags)

使用一个字节数组、一个密码和一个密钥存储标志初始化 X509Certificate2 类的新实例。

X509Certificate2(Byte[], String)

使用一个字节数组和一个密码初始化 X509Certificate2 类的新实例。

X509Certificate2(Byte[], String, X509KeyStorageFlags)

使用一个字节数组、一个密码和一个密钥存储标志初始化 X509Certificate2 类的新实例。

X509Certificate2(IntPtr)

使用非托管句柄初始化 X509Certificate2 类的新实例。

X509Certificate2(ReadOnlySpan<Byte>)

用证书数据初始化 X509Certificate2 类的新实例。

X509Certificate2(ReadOnlySpan<Byte>, ReadOnlySpan<Char>, X509KeyStorageFlags)

使用证书数据、密码和密钥存储标志初始化 X509Certificate2 类的新实例。

X509Certificate2(SerializationInfo, StreamingContext)

使用指定的序列化和流上下文信息初始化 X509Certificate2 类的新实例。

X509Certificate2(String)

使用证书文件名初始化 X509Certificate2 类的新实例。

X509Certificate2(String, ReadOnlySpan<Char>, X509KeyStorageFlags)

使用一个证书文件名、一个密码和一个密钥存储标志初始化 X509Certificate2 类的新实例。

X509Certificate2(String, SecureString)

使用一个证书文件名和一个密码初始化 X509Certificate2 类的新实例。

X509Certificate2(String, SecureString, X509KeyStorageFlags)

使用一个证书文件名、一个密码和一个密钥存储标志初始化 X509Certificate2 类的新实例。

X509Certificate2(String, String)

使用一个证书文件名和一个用于访问该证书的密码初始化 X509Certificate2 类的新实例。

X509Certificate2(String, String, X509KeyStorageFlags)

使用一个证书文件名、一个用于访问该证书的密码和一个密钥存储标志初始化 X509Certificate2 类的新实例。

X509Certificate2(X509Certificate)

使用 X509Certificate 对象初始化 X509Certificate2 类的新实例。

 

  直接 F12 也贴出来吧,方便大伙查看

 

   帅气的小伙伴可能已经发现了,里面就存在了一个 直接传入 文件路径 和 密码 作为参数的构造函数,毫无疑问,它就是我们要找的!!!下面我们直接看代码:

Program.cs

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        listenOptions.SslProtocols = SslProtocols.Tls13;
    });
    serverOptions.ListenAnyIP(5209, listenOptions =>
    {
        listenOptions.UseHttps(httpsOptions =>
        {
            var test1 = new X509Certificate2("cer\\test1.ysmc.net.cn_server.pfx", "密码1");
            var test2 = new X509Certificate2("cer\\test2.ysmc.net.cn_server.pfx", "密码2");
            var certs = new Dictionary<string, X509Certificate2>(
                StringComparer.OrdinalIgnoreCase)
            {
                ["test1.ysmc.net.cn"] = test1,
                ["test2.ysmc.net.cn"] = test2
            };

            httpsOptions.ServerCertificateSelector = (connectionContext, name) =>
            {
                if (name is not null && certs.TryGetValue(name, out var cert))
                {
                    return cert;
                }

                return test1;
            };
        });
    });
});

 

  因为是配合了 YARP “食用”的,详情可以查看我前面的文章,传送门,所以不同的域名会反向代理到不同的网站上面,好了,文章到此结束,感谢大佬们的阅读,谢谢!

原文链接:https://www.cnblogs.com/ysmc/p/16721268.html

版权声明:本文版权归作者所有,遵循 CC 4.0 BY-SA 许可协议, 转载请注明原文链接
https://www.cnblogs.com/ysmc/p/16721268.html

.net 反向代理-yarp 部署https(ssl)_一事冇诚-编程思维

  YARP 作为反向代理中间件,那就无可避免需要使用到 Https 去部署项目,那 YARP 要怎么去实现呢,本来以为 YARP 会有一套自己的实现,在翻阅了资料后发现,根本不是我想的那样,按照 YARP 官方文档的说法,是按照 .Net Core 原本的那一套去实现,好家伙,真的没想到啊,下面我贴出官方原文,大伙看

乘风破浪,遇见最佳跨平台跨终端框架.net core/.net生态_贯穿asp.net core整个架构的依赖注入框架(dependency injection)_taylorshi-编程思维

为什么需要依赖注入框架 借助依赖注入框架,可以轻松管理类之间的依赖,帮助我们在构建应用时遵循设计原则,确保代码的可维护性和可扩展性。 ASP.NET Core的整个架构中,依赖注入框架提供了对象创建和生命周期管理的核心能力,各个组件相互协作,也是依靠依赖注入框架的能力来实现的。 组件包 Microsoft.Ex

bootstrap blazor 开源ui库介绍-table 虚拟滚动行_一事冇诚-编程思维

  今天我们来介绍一下 Bootstrap Blazor 中 Table 组件的虚拟滚动行,什么是虚拟滚动呢,我查到的解释是:只渲染可视区域的列表项,非可见区域的 完全不渲染,在滚动条滚动时动态更新列表项。   然后很明显,在实际应用中不可能实现“非可见区域的 完全不渲染”,这样的体验效果太差了,下拉直接空白,所以一般

.net 反向代理 yarp 通过编码方式配置域名转发_一事冇诚-编程思维

  前面介绍了 YARP 通过配置文件的方式配置代理转发(传送门),而众所周知,微软的一贯作风就是能通过配置文件做的事情,通过编码的方式也能实现!YARP 也不例外,废话不多说,直接上代码!   首先,参照官方文档,我们先新建一个 InMemoryConfigProvider 类,并且继承 IProxyConfigPr

.net 反向代理 yarp 跨域请求 cors_一事冇诚-编程思维

  使用过 nginx 的小伙伴应该都知道,这个中间件是可以设置跨域的,作为今天的主角,同样的 反向代理中间件的 YARP 毫无意外也支持了跨域请求设置。   有些小伙伴可能会问了,怎样才算是跨域呢?   在 HTML 中,一些标签,例如 img、a 等,还有我们非常熟悉的 Ajax,都是可以指向非本站的资源的,那什么

第二课:c#工控上位机框架篇——界面 - 编程思维

话不多说,直接开始:步骤一:安装metroframework框架并引入工具箱,具体内容可以参考链接如下:如何在C# WinForms应用程序中安装,配置和使用MetroFramework(样式化接口组件)Attention!!!!文件路径最好不要含中文或者关键字,笔者因为含有#关键字报如下错误:步骤二:搭建页面框架——

.net 反向代理 yarp 通过编码方式配置域名转发_一事冇诚-编程思维

  前面介绍了 YARP 通过配置文件的方式配置代理转发(传送门),而众所周知,微软的一贯作风就是能通过配置文件做的事情,通过编码的方式也能实现!YARP 也不例外,废话不多说,直接上代码!   首先,参照官方文档,我们先新建一个 InMemoryConfigProvider 类,并且继承 IProxyConfigPr

使用coverlet统计单元测试的代码覆盖率_崩坏的领航员-编程思维

单元测试是个好东西, 可以在一定程度上兜底 虽然写单元测试这件事情非常麻烦 但是好的单元测试可以显著提高代码质量, 减少bug, 避免无意中的修改导致其他模块出错 写测试用例的过程中, 靠人力去确保所有代码都被覆盖是一件挺麻烦的事情 本文主要介绍如何在xunit下使用coverlet统计测试覆盖率 环境介绍 系统: w