在Azure上搭载以SSL方式访问的WcfService

 

在Azure上搭载以SSL方式访问的WcfService

 

搭载SSL的WcfService的方法:

创建一个Azure项目CollectorWebService和一个WcfService项目CollectorWebServiceRole。这两个项目都已经在Http下能正常访问。下面要把该WcfService修改为支持SSL的WcfService。

 

一、制作SSL的证书

该证书必须满足一下条件:

1、 该证书必须包含私钥

2、 该证书必须是支持密钥交换的.pfx文件

3、 该证书的subject必须匹配你发布的WcfService的域名,如:CloudMgr.cloudapp.net,而不能仅是cloudapp.net。

4、 该证书必须是最低2048位加密。

 

在Visual Studio Tools中启动Visual Studio命令行工具,制作证书的命令:

makecert -sky exchange -r -n "CN=CloudMgr.cloudapp.net" -pe -a sha1 -len 2048 -ss My "CloudMgr.cloudapp.net.cer"

此文,是以 CloudMgr.cloudapp.net为例制作的证书,在实际应用中自己需要根据相应Role的名称更改名称,YourAppName.cloudapp.net。

关于数字证书更多的信息,请参考 在.NET中操作数字证书  http://blog.csdn.net/zztfj/article/details/6036869 

 

然后,在“开始”菜单的“运行”中输入“certmgr.msc”进入“证书管理”的控制台页面。在“个人”文件夹下找到刚才创建的CloudMgr.cloudapp.net证书,右键“所有任务”——“导出”,输入在创建证书的时候输入的密码,即可导出.pfx文件。

 

二、上传该.pfx文件。

在Azure Management Portal中,创建CloudMgr的HostedService,然后,点击“添加证书”,选择刚才生成的.pfx文件,并输入对应的密码。

上传成功后,复制该证书的thumbprint以备用。

 

三、设置项目配置文件使其支持SSL。

1、依据下面的配置修改.csdef文件

  <WebRole name="CollectorWebServiceRole" vmsize="Small">
    <Sites>
      <Site name="Web">
        <Bindings>
          <Binding name="Endpoint1" endpointName="Endpoint1" />
        </Bindings>
      </Site>
    </Sites>
    <!--HTTPS SSL通信方式-->
    <Certificates>
      <Certificate name="CloudMgr.cloudapp.net" storeLocation="LocalMachine" storeName="CA" />
    </Certificates>
    <Endpoints>
      <InputEndpoint name="Endpoint1" protocol="https" port="443" certificate="CloudMgr.cloudapp.net" />
    </Endpoints>
    <!--HTTPS SSL 通信方式-->
    <!—HTTP 通信方式-->
    <!--<Endpoints>
      <InputEndpoint name="Endpoint1" protocol="http" port="80" />
    </Endpoints>-->
    <!—HTTP 通信方式-->
    <Imports>
      <Import moduleName="Diagnostics" />
    </Imports>
    <LocalResources>
      <LocalStorage name="CollectorWebServiceRole.svclog" sizeInMB="1000" cleanOnRoleRecycle="false" />
    </LocalResources>
    <ConfigurationSettings>
    </ConfigurationSettings>
  </WebRole>


 

   2、依据下面的配置修改.cscfg文件

  <Role name="CollectorWebServiceRole">
    <Instances count="1" />
    <ConfigurationSettings>
      <Setting name="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" value="UseDevelopmentStorage=true" />
    </ConfigurationSettings>
    <!--HTTPS SSL 通信方式-->
    <Certificates>
      <Certificate name="CloudMgr.cloudapp.net" thumbprint="9F11154439992F3AD04951E98175D7FFA72EDBAB" thumbprintAlgorithm="sha1" />
    </Certificates>
    <!--HTTPS SSL 通信方式-->
  </Role>


 

依据上面的步骤部署该WcfService后,会出现下面的错误提示:

 

Server Error in '/' Application.

Service 'CollectorWebServiceRole.Service' has zero application (non-infrastructure) endpoints. This might be because no configuration file was found for your application, or because no service element matching the service name could be found in the configuration file, or because no endpoints were defined in the service element.

 

Role工程的web.config文件中追加了下面的内容后,问题解决。

  <!--HTTPS SSL 通信方式-->
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="BasicHttpBinding_IService" closeTimeout="00:01:00"
            openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
            allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
            maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
            messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
            useDefaultWebProxy="true">
          <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="16384"
              maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <security mode="Transport">
            <transport clientCredentialType="None" proxyCredentialType="None"
                realm="" />
            <message clientCredentialType="UserName" algorithmSuite="Default" />
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>

    <services>
      <service name="CollectorWebServiceRole.Service">
        <endpoint address= "" binding="basicHttpBinding" contract="CollectorWebServiceRole.IService" bindingConfiguration="BasicHttpBinding_IService" />
        <endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange"/>

      </service>
    </services>

    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpsGetEnabled = "True"/>
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
  <!--HTTPS SSL 通信方式-->

  <!--HTTP  通信方式-->
  <!--<system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="BasicHttpBinding_IService" closeTimeout="00:01:00"
            openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
            allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
            maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
            messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
            useDefaultWebProxy="true">
          <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="16384"
              maxBytesPerRead="4096" maxNameTableCharCount="16384" />
        </binding>
      </basicHttpBinding>
    </bindings>

    <services>
      <service name="CollectorWebServiceRole.Service">
        <endpoint address= "" binding="basicHttpBinding" contract="CollectorWebServiceRole.IService" bindingConfiguration="BasicHttpBinding_IService" />
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>

      </service>
    </services>

    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled = "True"/>
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>-->
  <!--HTTP  通信方式-->


 

 

创建一个AzureWorker调用该AzureWcfService

创建一个AzureWorkerRole的工程,在该工程中“引用服务”,添加引用上面创建的WcfService,该步骤会自动生成一个本地代理类。现在要做的就是使该代理类在向使用SSLWcfService进行信息交互的时候使用指定的证书。

在引用WcfService之后,依据下面的配置修改app.config文件

  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="BasicHttpBinding_IService" closeTimeout="00:01:00"
            openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
            allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
            maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
            messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
            useDefaultWebProxy="true">
          <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="16384"
              maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <!--HTTPS SSL 通信方式-->
          <security mode="Transport">
            <transport clientCredentialType="None" proxyCredentialType="None"
                realm="" />
            <message clientCredentialType="UserName" algorithmSuite="Default" />
          </security>
          <!--HTTPS SSL 通信方式-->
        </binding>
      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint address="https://cloudmgr.cloudapp.net/service.svc" binding="basicHttpBinding"
          bindingConfiguration="BasicHttpBinding_IService" contract="CollectorService.IService"
          name="BasicHttpBinding_IService" />
    </client>
  </system.serviceModel>


 

把生成的.cer证书文件放在该WorkerRole工程下,修改文件的属性为“常复制”,使该证书与该工程一同发布。

 

修改代码使WcfService的代理类发送请求前使用证书。

    //向WcfService发送消息
    using (CollectorService.ServiceClient client = new CollectorService.ServiceClient())
    {
        //HTTPS SSL 通信方式,如果是Http通信,请删除该部分
        client.ClientCredentials.ClientCertificate.Certificate = new X509Certificate2(X509Certificate2.CreateFromCertFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "CloudMgr.cloudapp.net.cer")));
        ServicePointManager.ServerCertificateValidationCallback += RemoteCertificateValidate;
        //HTTPS SSL 通信方式,如果是Http通信,请删除该部分

        client.Post(data);
    }



        /// <summary>
        /// Remotes the certificate validate.
        /// </summary>
        private static bool RemoteCertificateValidate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors error)
        {
     //信任现在客户端使用的证书。为了解决下面这个错误:Could not establish trust relationship for the SSL/TLS secure channel with authority
            // trust any certificate!!!
            System.Console.WriteLine("Warning, trust any certificate");
            return true;
        }

 

至此,一个支持SSL方式访问的Azure服务和调用该服务的WorkerRole已经完成。

 

参考URL

https://www.windowsazure.com/en-us/develop/net/common-tasks/enable-ssl/

 

http://watwindows8.codeplex.com/wikipage?title=Appendix%20I%3a%20How%20to%20Deploy%20Your%20Services%20to%20Windows%20Azure%3f&version=3

 

 

 

 

你可能感兴趣的:(在Azure上搭载以SSL方式访问的WcfService)