我正在尝试发送一个需要X.509证书的SOAP服务。
在Soap UI中,我在SSL settings中设置了证书路径和密码,在请求窗口中输入信封,点击提交并获得结果。
在C#中它变得复杂,主要是因为我对这个东西很新。所以首先我尝试使用Send and Receive a SOAP Message By Using the SoapClient and SoapService Classes指南编写一个简单的消息发送方法,它的工作原理。
下一步是签署(我猜)带有证书的SOAP消息,还有一个指南,至少是一个Sign a SOAP Message Using an X.509 Certificate指南,所以现在我有一个类/方法可以发送SOAP消息和可以签署SOAP消息的类/方法。
但我不知道如何实际签名,我的代码看起来像这样:
public class SOAPTest
{
public static string Call(string argsUrl, string requestAction, string argsXml)
{
Uri destination_uri = new Uri(argsUrl);
EndpointReference destination = new EndpointReference(destination_uri);
SoapEnvelope envelope = new SoapEnvelope();
envelope.LoadXml(argsXml);
// The destination variable is the EndpointReference
// for the Web service.
TcpClient client = new TcpClient(destination);
SoapEnvelope returnEnvelope = client.RequestResponseMethod(envelope);
// The envelope that is returned is the response data.
return returnEnvelope.OuterXml;
}
}
我有Sign a SOAP Message Using an X.509 Certificate和Create a Custom Policy Assertion that Secures SOAP Messages中提到的所有类:CustomSecurityAssertion,CustomSecurityServerInputFilter,CustomSecurityServerOutputFilter,CustomSecurityClientInputFilter和CustomSecurityClientOutputFilter,最后一个看起来像这样,据我所知有SecureMessage
方法我需要用来签名信封:
class CustomSecurityClientOutputFilter : SendSecurityFilter
{
SecurityToken clientToken;
SecurityToken serverToken;
public CustomSecurityClientOutputFilter(CustomSecurityAssertion parentAssertion)
: base(parentAssertion.ServiceActor, true)
{
// Get the client security token.
clientToken = X509TokenProvider.CreateToken(StoreLocation.CurrentUser, StoreName.My, "CN=B2B");
// Get the server security token.
serverToken = X509TokenProvider.CreateToken(StoreLocation.LocalMachine, StoreName.My, "CN=B2B");
}
public override void SecureMessage(SoapEnvelope envelope, Security security)
{
X509SecurityToken signatureToken = GetSecurityToken("CN=B2B");
if (signatureToken == null)
{
throw new Exception("Message Requirements could not be satisfied.");
}
// Add the security token.
security.Tokens.Add(signatureToken);
// Specify the security token to sign the message with.
MessageSignature sig = new MessageSignature(signatureToken);
security.Elements.Add(sig);
}
public X509SecurityToken GetSecurityToken(string subjectName)
{
X509SecurityToken securityToken = null;
X509Store store = new X509Store(StoreName.My,
StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
try
{
X509Certificate2Collection certs =
store.Certificates.Find(X509FindType.FindBySubjectDistinguishedName,
subjectName, false);
X509Certificate2 cert;
if (certs.Count == 1)
{
cert = certs[0];
securityToken = new X509SecurityToken(cert);
}
else
securityToken = null;
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
finally
{
if (store != null)
store.Close();
}
return securityToken;
}
}
我如何"连接"这两个并得到我在Soap UI中得到的相同结果?
我是否至少在尝试签署邮件时做正确的事情?如果我尝试按原样运行我的项目,则会收到以下错误消息:
请求已中止:无法创建SSL / TLS安全通道。
但如果我提供错误的证书名称,我会收到错误:
基础连接已关闭:发送时发生意外错误。
所以看起来SOAP消息签名有效,但是服务器仍然拒绝连接,但是使用Soap UI和相同的证书以及相同的SOAP信封一切正常,没有问题,有什么建议吗?