如何解决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 举报,一经查实,本站将立刻删除。