https 与 Service Fabric 本地群集管理器

如何解决https 与 Service Fabric 本地群集管理器

我开发了 Service Fabric 应用程序,并在本地安装了 Service Fabric SDK,它提供了有用的 Service Fabric Local Cluster Manager (servicefabriclocalclustermanager.exe)(如果稀疏的话)。认情况下,这似乎只支持 http。没有明显的方法可以从 UI 创建 https 集群。我做了一些研究,并设法为自己创建了一个 https 集群,但为此我必须手动修改 ClusterConfig.json 文件并运行 CreateServiceFabriccluster.ps1 powershell 脚本。这不与 Service Fabric Local Cluster Manager 集成,如果我想操作它,我基本上必须使用 powershell 命令。这是可以管理的,但如果可能的话,只使用系统托盘小部件会容易得多。

有没有办法将 Service Fabric 本地集群管理器与为 https 配置的本地集群一起使用?我知道 C:\Program Files\Microsoft SDKs\Service Fabric\ClusterSetup 中有一大堆脚本,这似乎是 Service Fabric Local Cluster Manager 用来配置它与之交互的集群的内容,并且有那些脚本,但我不知道如何使用它们。

解决方法

这是我使用了很长时间的解决方案。

这里的关键是创建自己的自定义 Https 证书定位器 并使用它根据您的情况找到正确的证书 环境。例如,在本地使用默认值是有意义的 localhost 由 Visual Studio 工具创建的 HTTPs 证书。在 您可能需要根据以下条件识别正确证书的其他环境 一些标准,比如它的通用名称

覆盖 CreateServiceInstanceListeners 无状态服务中的 ASP.NET 操作以配置 https 端口。这也是您提供自定义 HttpsCertificateLocator 实现的地方。

protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
    return new ServiceInstanceListener[]
    {
        new ServiceInstanceListener(serviceContext =>
            new KestrelCommunicationListener(serviceContext,"ServiceEndpoint",(url,listener) =>
            {
                return new WebHostBuilder()
                    .UseKestrel(opt =>
                    {
                        int port = serviceContext.CodePackageActivationContext.GetEndpoint("ServiceEndpoint").Port;
                        opt.Listen(IPAddress.IPv6Any,port,listenOptions =>
                        {
                            listenOptions.UseHttps(new HttpsCertificateLocator().GetHttpsCertificateFromStore());
                        });
                    })
                      

示例 Https 证书定位器

public class HttpsCertificateLocator : BaseHttpsCertificateLocator,IHttpsCertificateLocator
{
    private readonly string[] _cNsToTryInOrderOfPriority;
    private readonly bool _isDevelopment;
    private const string Development = nameof(Development);

    public HttpsCertificateLocator(string environmentName = null,string[] cNsToTryInOrderOfPriority = null)
    {
        _cNsToTryInOrderOfPriority = cNsToTryInOrderOfPriority ?? CommonCertificates.Intranet.DefaultCNs;

        var environment = string.IsNullOrWhiteSpace(environmentName)
            ? (System.Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? Development)
            : environmentName;

        _isDevelopment = string.Compare(environment,Development,StringComparison.OrdinalIgnoreCase) == 0;
    }

    /// <summary>
    /// If environment is Development,finds and returns the ASP .NET Core HTTPS development certificate in development environment.
    /// In other developments,returns a HTTPS certificate that is assumed installed on all Service Fabric cluster nodes
    /// </summary>
    public X509Certificate2 GetHttpsCertificateFromStore(bool httpsMandatory = true)
    {
        if (_isDevelopment)
        {
            return ReturnDevCertificate(httpsMandatory);
        }

        using (X509Store store = new X509Store(StoreName.My,StoreLocation.LocalMachine))
        {
            store.Open(OpenFlags.ReadOnly);
            var certCollection = store.Certificates;

            foreach (var subjectName in _cNsToTryInOrderOfPriority)
            {
                var matchingCerts = certCollection.Find(X509FindType.FindBySubjectDistinguishedName,subjectName,true);
                if (matchingCerts.Count > 0)
                {
                    return EnsureMostRecentCertificate(matchingCerts,httpsMandatory);
                }
            }

            return EnsureMostRecentCertificate(
                new X509Certificate2Collection(),_cNsToTryInOrderOfPriority.LastOrDefault() ?? "<NONE SPECIFIED>",httpsMandatory);
        }
    }
}

以上代码继承自BaseHttpsCertificateLocator。它提供了额外的功能来定位默认的开发 localhost HTTPs 证书。它还具有用于查找最新证书的代码(您在开始滚动证书时必须处理的问题)。

public abstract class BaseHttpsCertificateLocator
{
    protected X509Certificate2 ReturnDevCertificate(bool httpsMandatory)
    {
        // Note: AspNet Core should auto generate/install this X509 cert on dev PCs
        const string aspNetHttpsOid = "1.3.6.1.4.1.311.84.1.1";
        const string cnLocalhost = "CN=localhost";

        using (X509Store store = new X509Store(StoreName.My,StoreLocation.LocalMachine))
        {
            store.Open(OpenFlags.ReadOnly);
            var certCollection = store.Certificates;
            var currentCerts = certCollection.Find(X509FindType.FindByExtension,aspNetHttpsOid,true);
            var matchingCerts = currentCerts.Find(X509FindType.FindByIssuerDistinguishedName,cnLocalhost,true);
            return EnsureMostRecentCertificate(matchingCerts,httpsMandatory);
        }
    }

    protected X509Certificate2 EnsureMostRecentCertificate(
        X509Certificate2Collection marchingCerts,string cnName,bool httpsMandatory)
    {
        if (marchingCerts.Count == 0)
        {
            return httpsMandatory
                ? throw new SecurityException($"Unable to locate HTTPS X509 cert `{cnName}`")
                : default(X509Certificate2);
        }

        if (marchingCerts.Count > 1)
        {
            return marchingCerts.Cast<X509Certificate2>().OrderByDescending(x => x.NotAfter).First();
        }

        return marchingCerts[0];
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?