Service Fabric Asp.Net Core无状态服务上的HTTP和HTTPS端点

时间:2016-11-15 10:16:27

标签: azure-service-fabric

我有一个Service Fabric无状态Asp.Net核心服务。

该服务适用于HTTP端点。 我需要支持HTTPS端点以及HTTP

到目前为止我的步骤:

  1. 将证书添加到Azure KeyVault
  2. 使用以下命令更新了ApplicationManifest.xml:

    <Policies>
      <EndpointBindingPolicy EndpointRef="ServiceEndpointHttps" CertificateRef="Certificate" />
    </Policies>
    
  3. 最后

    <Certificates>
        <EndpointCertificate X509StoreName="MY" X509FindValue="XXXX" Name="Certificate" />
      </Certificates>
    
    1. 在ServiceManifest.xml中添加了端口443
    2. 的端点

      我现在离开了启用HTTPS端点。 在Program.cs中我有这个:

        public static void Main(string[] args)
              {
                  ServiceRuntime.RegisterServiceAsync("MyType", context => new WebHostingService(context, "ServiceEndpoint")).GetAwaiter().GetResult();
      
                  Thread.Sleep(Timeout.Infinite);
              }
       internal sealed class WebHostingService : StatelessService, ICommunicationListener
              {
                  private readonly string _endpointName;
      
                  private IWebHost _webHost;
      
                  public WebHostingService(StatelessServiceContext serviceContext, string endpointName)
                      : base(serviceContext)
                  {
                      _endpointName = endpointName;
                  }
      
                  #region StatelessService
      
                  protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
                  {
                      return new[] { new ServiceInstanceListener(_ => this) };
                  }
      
                  #endregion StatelessService
      
                  #region ICommunicationListener
      
                  void ICommunicationListener.Abort()
                  {
                      _webHost?.Dispose();
                  }
      
                  Task ICommunicationListener.CloseAsync(CancellationToken cancellationToken)
                  {
                      _webHost?.Dispose();
      
                      return Task.FromResult(true);
                  }
      
                  Task<string> ICommunicationListener.OpenAsync(CancellationToken cancellationToken)
                  {
                      var endpoint = FabricRuntime.GetActivationContext().GetEndpoint(_endpointName);
      
                      string serverUrl = $"{endpoint.Protocol}://{FabricRuntime.GetNodeContext().IPAddressOrFQDN}:{endpoint.Port}";
      
                      _webHost = new WebHostBuilder().UseKestrel()
                                                     .UseContentRoot(Directory.GetCurrentDirectory())
                                                     .UseStartup<Startup>()
                                                     .UseUrls(serverUrl)
                                                     .Build();
      
                      _webHost.Start();
      
                      return Task.FromResult(serverUrl);
                  }
      
                  #endregion ICommunicationListener
              }
      

      如何在此注册HTTPS端点?

      添加第二个ServiceRuntime.RegisterServiceAsync不起作用。

      此外,启用它之后,我如何安装(从门户网站或powershell)将证书从KeyVault安装到已部署并运行的虚拟机规模集?

3 个答案:

答案 0 :(得分:2)

你实际上可以使用Kestrel + HTTPS + Service Fabric,但它更像是一次冒险。

1)您需要自己找到证书(见下文) 2)如果您在本地计算机上进行测试,则需要将证书添加到LocalMachine,并确保您授予NETWORK SERVICE(mmc \ Certificate \ Local Machine \ Personal \ Cert,右键单击所有任务\管理私钥)的权限...)

        private X509Certificate2 FindCertificate(string thumbprint)
        {
            X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
            try
            {
                store.Open(OpenFlags.ReadOnly);
                X509Certificate2Collection col = store.Certificates.Find(X509FindType.FindByThumbprint,
                    thumbprint, false); // Don't validate certs, since the test root isn't installed.
                if (col == null || col.Count == 0)
                    return null;
                return col[0];
            }
            finally
            {
                store.Close();
            }
        }

        Task<string> ICommunicationListener.OpenAsync(CancellationToken cancellationToken)
        {
            var endpoint = FabricRuntime.GetActivationContext().GetEndpoint(_endpointName);

            string serverUrl = $"{endpoint.Protocol}://{FabricRuntime.GetNodeContext().IPAddressOrFQDN}:{endpoint.Port}";

            _webHost = new WebHostBuilder().UseKestrel(options =>
                                            {
                                                options.UseHttps(FindCertificate("<thumbprint-remove-magic-character at the beginning if copy&paste from MMC>"));
                                            })

答案 1 :(得分:0)

我周末才遇到这个。我遵循了一些建议,因为不使用Kestrel而是使用WebListener:

new WebHostBuilder()
.UseWebListener()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.UseUrls($"{endpoint.Protocol}://+:{endpoint.Port}")
.Build();

另请注意,使用+代替网址      FabricRuntime.GetNodeContext().IPAddressOrFQDN

希望这有帮助。

答案 2 :(得分:0)

我使用Azure应用程序网关解决了问题。