簡體   English   中英

不帶IIS的HTTPS上的WCF服務,帶有來自CERT和KEY字符串或文件的SSL證書

[英]WCF Service over HTTPS without IIS, with SSL Certificate from CERT and KEY strings or files

我之前曾與WCF進行過合作-但由於它僅用於內部使用,根本無法從Internet訪問,因此我只是使用net.tcp而不關心安全性。

但是,我現在正在准備一個項目,該項目可以通過Internet向客戶提供,因此必須計划安全性。

我一直在對此事進行一些研究,從我收集到的信息(如果我在這里錯了,請更正),HTTPS是我最好的選擇,因為HTTP根本不受保護(默認情況下),並且net.tcp可以找到一些防火牆的問題。

Howerer,我不想強​​迫客戶在不需要的服務器上安裝IIS,因此計划是使用自托管的Windows Service。 但是,我似乎找不到有關如何設置服務器以在沒有IIS的情況下使用HTTPS的任何信息。

  1. 我發現了有關使用makecerthttpcfg set ssl向存儲中添加新證書,然后將其設置為端口的信息-可以進行測試,但是我在客戶的服務器中看不到這一點-更不用說這意味着我將使用自己簽署的證書-再次可以進行測試,而在生產中則不需要太多

  2. 我還找到了有關使用類似信息的信息( ServiceCredentials MSDN頁面

     sh.Credentials.ServiceCertificate.SetCertificate( StoreLocation.LocalMachine, StoreName.My, X509FindType.FindByThumbprint, "af1f50b20cd413ed9cd00c315bbb6dc1c08da5e6"); 

設置服務器證書存儲區中已經存在的證書-幾乎可以-仍然需要客戶知道如何管理存儲區中的證書,雖然不完美,但是還可以。 但是我無法使它正常工作-啟動Servisse時沒有任何錯誤,但是如果我嘗試在瀏覽器中轉到服務地址,則會收到關於TLS蜂鳴聲過時的錯誤-Q1:任何想法可能是這里的問題嗎?

問題2:是否有可能在某個地方進行配置,客戶可以在其中購買購買證書並使用其來確保服務安全的證書和密鑰文件的輸入或至少輸入位置?

Q1:如錯誤所述,您的證書可能存在問題。 確保證書有效(自簽名證書不能過期)。
Q2:據我所知,我們可以將證書另存為文件(pfx,cert)或將證書安裝在證書存儲區(certlm.msc,certmgr.msc)中以便進行管理。
是否要在Windows服務項目中通過https托管WCF服務? 我做了一個演示,希望對您有用。
Service1.cs

public partial class Service1 : ServiceBase
        {
            public Service1()
            {
                InitializeComponent();
            }
            Uri uri = new Uri("https://localhost:1017");
            ServiceHost sh = null;
            protected override void OnStart(string[] args)
            {
                BasicHttpBinding binding = new BasicHttpBinding();
                binding.Security.Mode = BasicHttpSecurityMode.Transport;
                binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
                try
                {
                    ServiceHost sh = new ServiceHost(typeof(MyService), uri);
                    sh.AddServiceEndpoint(typeof(IService), binding, "");
                    ServiceMetadataBehavior smb;
                    smb = sh.Description.Behaviors.Find<ServiceMetadataBehavior>();
                    if (smb == null)
                    {
                        smb = new ServiceMetadataBehavior()
                        {
                            HttpsGetEnabled=true,
                        };
                        sh.Description.Behaviors.Add(smb);
                    }
                    Binding mexbinding = MetadataExchangeBindings.CreateMexHttpsBinding();
                    sh.AddServiceEndpoint(typeof(IMetadataExchange), mexbinding, "mex");
                    sh.Open();
                    WriteLog($"Service is ready at {DateTime.Now.ToString("hh-mm-ss")}");
                }
                catch (Exception e)
                {
                    WriteLog(e.ToString());
                    throw;
                }
            }

            protected override void OnStop()
            {
                if (sh!=null&&sh.State==CommunicationState.Opened)
                {
                    sh.Close();
                    WriteLog($"Service is closed at {DateTime.Now.ToString("hh-mm-ss")}");
                }
            }

            public static void WriteLog(string text)
            {
                using (StreamWriter sw = File.AppendText(@"C:\Mylog.txt"))
                {
                    sw.WriteLine(text);
                    sw.Flush();
                }
            }
        }
        [ServiceContract(Namespace = "mydomain")]
        public interface IService
        {
            [OperationContract]
            string SayHello();
        }
        public class MyService : IService
        {
            public string SayHello()
            {
                Service1.WriteLog(string.Format("Wow, I have been called at {0}", DateTime.Now.ToString("hh-mm-ss")));
                return "Hello stranger";
            }
    }

ProjectInstaller.cs
在此處輸入圖片說明
在此處輸入圖片說明
安裝Windows服務(管理員權限CMD)
在此處輸入圖片說明
將證書綁定到應用程序端口。
在此處輸入圖片說明
https://docs.microsoft.com/en-us/windows/desktop/http/add-sslcert
https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-configure-a-port-with-an-ssl-certificate
Certhash參數指定證書的指紋。 appid參數是一個GUID,可用於標識擁有的應用程序(打開project.csproj文件)

<ProjectGuid>{56FDE5B9-3821-49DB-82D3-9DCE376D950A}</ProjectGuid>

啟動Windows服務。
在此處輸入圖片說明
測試(服務器IP為10.157.13.70):
在此處輸入圖片說明
客戶端調用(默認情況下有一個驗證服務器證書的步驟)

static void Main(string[] args)
    {
        ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;
        ServiceReference1.ServiceClient client = new ServiceReference1.ServiceClient();
        try
        {
            var result = client.SayHello();
            Console.WriteLine(result);
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }

結果
在此處輸入圖片說明
請隨時告訴我是否有什么我可以幫助的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM