這是我在網上的第一個問題。希望它是有道理的。使用從WCF服務到Java的X.509證書籤署SOAP消息web服務
我在網上看到過幾個與這個問題有關的博客,我嘗試了幾個沒有成功的想法。這是我的情況:
我有一個Web應用程序調用一個WCF Web服務,然後調用Java Web服務。他們都在不同的服務器上。 WCF Web服務與Java Web服務之間的調用未超過https,因爲證書足以標識調用方(因此消息安全性)。
- 的Java Web服務(黑盒子)
Java Web服務要求接收的簽名消息,並可以作爲每下面:每個請求被處理的處理程序截取所有傳入的消息之前
並執行以下驗證規則:
1.郵件是否包含安全標頭
2.郵件是否包含正確的安全標頭ID
3.郵件是否被正確簽名
4.郵件中是否包含KeyInfo x.509證書
5.證書是否來自可信CA-基於配置的
6.證書是否有效(未過期,撤銷)
7.證書是否包含正確的策略OID
一旦所有這些步驟都已確認,則可以處理消息,如果任何步驟失敗,則會返回肥皂消息異常。
SOAP安全性標頭應根據xxx ... w3.org/TR/SOAP-dsig/數字簽名規範進行驗證。
最完整的描述可以在這裏找到xxx ... ibm.com/developerworks/webservices/library/ws-security.html這篇IBM文章列出了每個WS-Security頭的詳細信息,另外還有一個簽名的SOAP消息示例已提供。
簽名SOAP消息時,您還必須將他們的x.509證書添加到證書驗證所需的消息KeyInfo中。
SOAP請求應該是這樣的:
<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Header>
<ds:Signature xmlns:ds="xxx...w3.org/2000/09/xmldsig#" Id="Signature001">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="xxx...w3.org/TR/2001/REC-xml-c14n-20010315"/>
<ds:SignatureMethod Algorithm="xxx...w3.org/2000/09/xmldsig#rsa-sha1"/>
<ds:Reference URI="">
<ds:Transforms>
<ds:Transform Algorithm="xxx...w3.org/2000/09/xmldsig#enveloped-signature"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="xxx...w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>soe1PnaGXVGrsauC61JSHD+uqGw=</ds:DigestValue>
</ds:Reference>
<ds:Reference URI="#KeyInfo001">
<ds:DigestMethod Algorithm="xxx...w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>Y9SRPQ9TcDu+GazO3LFwodEdhaA=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>jBX/8XkY2aCte7qgXEp1sbNWmQcK/90iVL58sAvwYAEcBABGzOk2agxR0HvWrNa6ixkocAQ205lggwOxnxZJvoVozVYAAjcLtayPBOUYrnSEBFrwKWP/vxgvUDRIdXeIuw5GLY87NrTQMm1Ehf/HvMX9hTBJn4Nm8RdDiUmPcIo=</ds:SignatureValue>
<ds:KeyInfo Id="KeyInfo001">
<ds:X509Data>
<ds:X509Certificate>MIIEbZCCA1WgAwIBAgIES1XpMjANBgkqhkiG9w0BAQUFADBYMRUwEwYKCZImiZPyLGQBGRYFbG9jYWwxFzAVBgoJkiaJk/IsZAEZFgdlbnRydXN0MRIwEAYDVQQDEwllbnRydXN0U00xEjAQBgNVBAMTCWVudHJ1c3RDQTAeFw0xMDA0MjIxMDQ4MDBaFw0xMzA0MjIxMTE4MDBaMGoxFTATBgoJkiaJk/IsZAEZFgVsb2NhbDEXMBUGCgmSJomT8ixkARkWB2VudHJ1c3QxEjAQBgNVBAMTCWVudHJ1c3RTTTESMBAGA1UEAxMJZW50cnVzdENBMRAwDgYDVQQDEwdSYnMgUmJzMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMf88L2JjLPG1hNmTA/KBiC53WVwS2WU9Jh3lC1Rob6RMzOojomZ/dNrvSRB6nzWeXJpZXwik4XFrsAq24By2SZpLTO4p8Vcq71mTAfDu33cnO49Au2pwNvcMn5qIKBk1Xx+oVb4fzK9ncTRu7bW46HsIYth+qkGhbI2JEHwr/zwIDAQABo4IBrzCCAaswCwYDVR0PBAQDAgeAMCsGA1UdEAQkMCKADzIwMTAwNDIyMTA0ODAwWoEPMjAxMjA1MjgxNTE4MDBaMCMGA1UdIAQcMBowCwYJYIZIAYb6awoEMAsGCSqGSIb2fQdLAzAbBgNVHQkEFDASMBAGCSqGSIb2fQdEHTEDAgEBMIHGBgNVHR8Egb4wgbswb6BtoGukaTBnMRUwEwYKCZImiZPyLGQBGRYFbG9jYWwxFzAVBgoJkiaJk/IsZAEZFgdlbnRydXN0MRIwEAYDVQQDEwllbnRydXN0U00xEjAQBgNVBAMTCWVudHJ1c3RDQTENMAsGA1UEAxMEQ1JMMTBIoEagRIZCZmlsZTovLy8vTVNJREhVLTQ0NUE0RkVFL0NSTC9lbnRydXN0Y2FfZW50cnVzdHNtX2xvY2FsX2NybGZpbGUuY3JsMB8GA1UdIwQYMBaAFBvSL6cPz8L5shubV58yf0pczKzuMB0GA1UdDgQWBBT1/j6OSS8FTjwqluvew16sv7h+VzAJBgNVHRMEAjAAMBkGCSqGSIb2fQdBAAQMMAobBFY4LjADAgSwMA0GCSqGSIb3DQEBBQUAA4IBAQBXxRIA4HUvGSw4L+4uaR51pY4ISjUQWo2Fh7FYBMt29NsKCTdur1OWVVdndt1yjXP4yWXxoAhHtvZL+XNALUFlR2HAWiXuL1nRcxHkB98N5gPqQzW/lJk9cLtL4hVp28EiEpgmKT3I3NP2Pdb2G5MMOdvQ/GFb2y6OwblR8ViPQ8B2aHWzXMrH+0qadPAuBhXyAohwb+mMuYT/ms6xpGi1NMYuYMf6XONz9GkZgnGnMwa+9CCQws1HNz8WYHtmFIxLsVuEWc/0a1vg4IYX1Ds/ttyhJGTVXOSJSkBz8kRyj1pNBDdc1KeG8M++O8m8VgRTJvYaPc7NMiclISukGpea</ds:X509Certificate> </ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
</S:Header>
<S:Body Id="ABC">
<ns2:createUser xmlns:ns2="http://webservice.rbs.emea.ps.entrust.com/" xmlns:ns3="http://webservice.rbs.emea.ps.entrust.com/types/CertificateException" xmlns:ns4="http://webservice.rbs.emea.ps.entrust.com/types/UserException">
<userID>0061020051</userID>
</ns2:createUser>
</S:Body>
</S:Envelope>
- WCF Web服務
我有(來自受信任的CA P7B格式)一個服務器證書,我安裝在我的WCF的Web服務工作站(dev)通過使用mmc證書管理單元(此時cert位於受信任發佈者處)。我不認爲我需要Java服務器上的另一個證書,因爲響應應該清晰(既不簽名也不加密)。我對這個證書和一般證書都有點困惑 - 因爲它似乎只保存一個公鑰。
這是應用程序。我的測試項目的配置:
<client>
<endpoint address="http://entrust-user-certification-uat.fm.rbsgrp.net/rbs/WebAS"
behaviorConfiguration="endpointCredentialsBehavior" binding="wsHttpBinding"
bindingConfiguration="WebAsServicePortTypeBinding" contract="IWebAsServicePortType"
name="WebAsServicePortType">
<!--<identity>
<dns value="entrust-user-certification-uat.fm.rbsgrp.net" />
</identity>-->
</endpoint>
</client>
<bindings>
<wsHttpBinding>
<binding name="WebAsServicePortTypeBinding" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text"
textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="Message">
<message clientCredentialType="Certificate" negotiateServiceCredential="false"
establishSecurityContext="false" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="endpointCredentialsBehavior">
<clientCredentials>
<clientCertificate findValue="entrust-user-certification-uat.fm.rbsgrp.net"
storeLocation="LocalMachine" storeName="TrustedPublisher"
x509FindType="FindBySubjectName"></clientCertificate>
<serviceCertificate>
<!--
Setting the certificateValidationMode to PeerOrChainTrust means that if the certificate
is in the user's Trusted People store, then it will be trusted without performing a
validation of the certificate's issuer chain. This setting is used here for convenience so that the
sample can be run without having to have certificates issued by a certificate authority (CA).
This setting is less secure than the default, ChainTrust. The security implications of this
setting should be carefully considered before using PeerOrChainTrust in production code.
-->
<authentication certificateValidationMode="None" revocationMode="NoCheck" trustedStoreLocation="LocalMachine"/>
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
當我運行一個簡單的測試:
WebAS entrustService =新WebAS();
ActivationCodes certCodes = entrustService.createUser(「testNomad」);
我已經得到了錯誤:
失敗:服務器無法處理 javax.xml.soap.SOAPException:未在SOAP消息中的Signature元素
怎麼可能我強制每個消息的簽名過程?我想我可以很容易地通過WCF配置來完成它。任何幫助將不勝感激 !
嗨Nomadefv, 你怎麼了,在IClientMessageInspector/BeforeSendReques注入你返回的XML字符串轉換成要求? AJR – 2011-02-08 11:06:29
對不起。在過去的幾周裏有點過時。您可以嘗試: – Nomadefv 2011-02-23 17:50:24
'公共對象BeforeSendRequest(請參閱System.ServiceModel.Channels.Message請求,System.ServiceModel。IClientChannel頻道) '{// ...從安全配置設置中獲取不同的變量 '//從證書存儲中加載證書。 'X509Certificate2 cert = GetCertificateBySubject(certificateSubjectName,certificateStoreName,certificateStoreLocation); '//簽署請求 'string signedSoapMessage = SignRequest(request.ToString(),cert,signatureId,keyInfoRefId,bodyId); – Nomadefv 2011-02-23 17:57:22