概述
因此,我一直在尝试在云服务上托管的 WCF 服务(使用 webrole)和 Salesforce 标注之间创建相互(2 路)SSL 连接。我正在创建一个大问题来概述我已采取的所有步骤以及我目前遇到的困难。
过程/进展
1:在 Azure 云服务上设置 SSL(成功)
- 已创建将 SSL 域(service.mydomain.com)指向 Azure 生产端点(service.cloudapp.net)的 CNAME <
- 已将签名证书上传到 Azure
- 向 WebRole 添加了证书并使用证书配置了 Https 端点
- 使用 Security Mode="Transport"创建 WCF web.config 绑定(bind)
完成此操作后,单向 SSL 可以正常工作
2:使用 salesforce 创建客户端证书。这是由 salesforce 颁发的未签名证书。您可以将其下载为 .cer(完成)
3:使用启动任务安装 Salesforce 客户端证书 ( see this article )(已完成,但我不确定如何确认它确实有效,除了部署时没有引发错误之外)
4:设置 WCF 以要求客户端证书(完成,请参阅 web.config)
5:使用 WebRole 中的启动任务解锁 VM IIS webserver/security/access/sslflags 和 覆盖 WCF web.config 中的设置(完成,请参阅startup.cmd 和 web.config)
显然,对于云服务,启动任务将在虚拟机上实际配置 IIS 之前运行。因此,我不得不使用 ping 来延迟并在后台运行。这实际上似乎和我收到 500 - 配置错误之前一样有效。
6:在 SF 请求中发送客户端证书(完成,请参阅 SF 代码)
结果: 我从服务器收到 403.7 - 禁止错误。我认为这与服务不信任 SF 证书有关,但我可以确定。由于系统的云到云性质,显然几乎不可能进行测试。
更新
因此,我能够通过将存储从“root”更改为“ca”来解决 403.7 错误。但是现在我正在处理一个不一致的问题,有时 start.cmd 似乎有效,而有时它似乎没有任何效果或仅产生部分效果。如果我重新启动我的服务,它会在配置标志被 IIS 锁定的 500 个错误、上面提到的 403.7 错误之间循环,而且它实际上工作得很好。
我找到了这个blog post使用自定义程序 (ExecWithRetries.exe) 延迟并重试启动任务,直到它们成功完成,但我仍然没有得到不一致的结果(可能是因为 appcmd 可能不会抛出错误,即使它在 VM 配置 IIS 之前运行) ?)。
我的startup.cmd现在的样子:
%windir%\System32\inetsrv\appcmd.exe unlock config /section:system.webServer/security/access
REM certutil -addstore -enterprise -f -v root Startup\MagnetClient.cer
certutil -addstore ca Startup\MagnetClient.cer
任务配置如下:
<startup>
<Task commandLine="Startup/ExecWithRetries.exe "/c:AddCert.cmd" /d:60000 /r:20 /rd:5000" executionContext="elevated" taskType="background" />
</startup>
如果任何人都能找到获得一致结果的解决方案,我将奖励他们。
代码引用
WCF web.config
<configuration>
<system.web>
<customErrors mode="Off"></customErrors>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service name="WCFServiceWebRole1.Service1" behaviorConfiguration="metadata" >
<endpoint name="basicHttp"
binding="basicHttpBinding"
bindingConfiguration="https"
contract="WCFServiceWebRole1.IService1" >
</endpoint>
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="https">
<!-- Step 1 -->
<security mode="Transport">
<!-- step 4 -->
<transport clientCredentialType="Certificate" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="metadata">
<serviceMetadata httpsGetEnabled="true" />
<!--<serviceDebug includeExceptionDetailInFaults="true"/>-->
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<httpErrors errorMode="Detailed"/>
<asp scriptErrorSentToBrowser="true" />
<modules runAllManagedModulesForAllRequests="true"/>
<!-- Override iis config mentioned in step 5 -->
<security>
<access sslFlags="SslRequireCert"/>
</security>
</system.webServer>
</configuration>
WebRole 服务定义
<ServiceDefinition name="WindowsAzureProject1" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition" schemaVersion="2013-03.2.0">
<WebRole name="WCFServiceWebRole1">
<!-- step 3 & 5 -->
<Startup>
<Task commandLine="Startup/startup.cmd" executionContext="elevated" taskType="background">
</Task>
</Startup>
<Sites>
<Site name="Web">
<Bindings>
<Binding name="Endpoint1" endpointName="Endpoint1" />
<Binding name="Endpoint2" endpointName="Endpoint2" />
</Bindings>
</Site>
</Sites>
<Endpoints>
<InputEndpoint name="Endpoint1" protocol="http" port="80" />
<!-- step 1 -->
<InputEndpoint name="Endpoint2" protocol="https" port="443" certificate="example.example.com" />
</Endpoints>
<Imports>
<Import moduleName="Diagnostics" />
</Imports>
<LocalResources>
<LocalStorage name="WCFServiceWebRole1.svclog" sizeInMB="1000" cleanOnRoleRecycle="false" />
</LocalResources>
<Certificates>
<!-- Step 1 -->
<Certificate name="example.example.com" storeLocation="LocalMachine" storeName="My" />
<Certificate name="Go Daddy Secure Certification Authority" storeLocation="LocalMachine" storeName="Trust" />
<Certificate name="Go Daddy Class 2 Certification Authority" storeLocation="LocalMachine" storeName="Trust" />
</Certificates>
<ConfigurationSettings>
</ConfigurationSettings>
</WebRole>
</ServiceDefinition>
startup.cmd
REM *HACK to wait a ridiculously long time until we can be
REM *pretty sure the VM has initialized IIS
ping -n 600 127.0.0.1 nul
%windir%\System32\inetsrv\appcmd.exe unlock config /section:system.webServer/security/access
REM add SF client certy to root store
certutil -addstore -enterprise -f -v root Statup\ClientCert.cer
销售人员示例代码
string b = '';
b = b + '<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body>';
b = b + '<TestService xmlns="http://tempuri.org/">';
b = b + '<echoString>test Message</echoString>';
b = b + '</TestService></s:Body></s:Envelope>';
Http h = new Http();
HttpRequest req = new HttpRequest();
//this should add the certificate created by salesforce
req.setClientCertificateName('MyClientCert');
req.setMethod('POST');
req.setEndpoint('https://service.mydomain.com/service1.svc');
req.setHeader('Content-type','text/xml');
req.setHeader('SoapAction', 'http://tempuri.org/IService1/TestService');
req.setBody( b );
HttpResponse res = h.send(req);
string m = res.getbody();
System.Debug(m);
最佳答案
我将提供一些建议:
- Enable RemoteAccess到您的 azure 部署并重新部署。然后登录并通过 MMC 访问证书存储以查看 SalesForce 客户端证书是否实际已安装。
- 添加
<Runtime executionContext="elevated" />
就在<WebRole name="WCFServiceWebRole1">
之后在您的服务配置中(请参阅我对此的回答 SO Post )以确保工作进程可以访问证书存储。
关于azure - Azure 云服务和 Salesforce 之间的相互(2 路)SSL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18086107/