通过 "Service Reference" 连接到 SSL SOAP 主机并通过安全 Header
Connect to SSL SOAP Host via "Service Reference" and pass Security Header
我正在尝试使用服务参考通过 C# 连接到 SSL SOAP 服务主机。
这是我的请求消息:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
<VsDebuggerCausalityData xmlns="http://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink">uIDPo/zwMmtdsVhFsAVDkQbiV/4AAAAA1zXtnc72UEm+4tlKzvCxsvN6OC2prvRIljIX4XzHKEYACQAA</VsDebuggerCausalityData>
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<u:Timestamp u:Id="_0">
<u:Created>2016-03-18T12:45:27.558Z</u:Created>
<u:Expires>2016-03-18T12:50:27.558Z</u:Expires>
</u:Timestamp>
<o:UsernameToken u:Id="uuid-2c7986ba-eee5-4411-90a9-a02b625c55ff-1">
<o:Username>MyUserName</o:Username>
<o:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">MyPlainPassword</o:Password>
</o:UsernameToken>
</o:Security>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<generateId xmlns="http://com.vedaadvantage/dp3/Enterprise/StandardTradeCreditCommercial/IndividualCommercialService"/>
</s:Body>
</s:Envelope>
这是我的服务发送给主机的消息。但是主机returns如下:
安全处理器无法在邮件中找到安全 header。这可能是因为消息是不安全的错误,或者是因为通信双方之间的绑定不匹配。如果服务配置为安全而客户端未使用安全性,则可能会发生这种情况。
这是我的配置文件:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<customBinding>
<binding name="myBinding">
<textMessageEncoding messageVersion="Soap11" />
<security authenticationMode="UserNameOverTransport"
messageSecurityVersion="WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10" >
</security>
<httpsTransport />
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="https://{URL}"
binding="customBinding"
bindingConfiguration="myBinding"
contract="ServiceReference2.MyService"
name="IndividualCommercialService" />
</client>
</system.serviceModel>
</configuration>
虽然当我通过 SOAPUI 或其他 HTTP Post 方法发送相同的 XML 时它工作正常。
我还提取并附加了证书和 user/pass,如下所示:
private static X509Certificate2 DownloadSslCertificate(string strDNSEntry)
{
X509Certificate2 cert = null;
using (TcpClient client = new TcpClient())
{
//ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
client.Connect(strDNSEntry, 443);
SslStream ssl = new SslStream(client.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null);
try
{
ssl.AuthenticateAsClient(strDNSEntry);
}
catch (AuthenticationException e)
{
//log.Debug(e.Message);
ssl.Close();
client.Close();
return cert;
}
catch (Exception e)
{
//log.Debug(e.Message);
ssl.Close();
client.Close();
return cert;
}
cert = new X509Certificate2(ssl.RemoteCertificate);
ssl.Close();
client.Close();
return cert;
}
}
private static void Main(string[] args){
var proxy = new MyService();
var uri = proxy.Endpoint.Address.Uri;
var cer = DownloadSslCertificate(uri.DnsSafeHost);
EndpointIdentity identity = EndpointIdentity.CreateDnsIdentity(cer.Subject.Replace("CN=", ""));
EndpointAddress address = new EndpointAddress(proxy.Endpoint.Address.Uri, identity);
proxy.Endpoint.Address = address;
proxy.ClientCredentials.UserName.UserName = "MyUserName";
proxy.ClientCredentials.UserName.Password = "MyPlainPassword";
proxy.ClientCredentials.ServiceCertificate.DefaultCertificate = cer;
proxy.HellowWorld();
}
我不确定我获取证书的方法是否正确,也不确定为什么 HTTP Post 有效但我的服务参考调用无效。
在此先感谢您的帮助。
干杯
尝试查看 WSDL(服务引用)以便首先查看隐藏文件 select 在解决方案资源管理器中显示所有文件。
您将在服务引用 Reference.svcmap -> Reference.cs 中看到,并在此文件中添加 ProtectionLevel = System.Net.Security.ProtectionLevel.Sign
如下图
[System.ServiceModel.ServiceContractAttribute(Namespace = "http://www.your.url/Service/", ConfigurationName = "Service.Service", ProtectionLevel = System.Net.Security.ProtectionLevel.Sign)]
应该对你有帮助。通常修改自动生成的代理是一个非常糟糕的主意,但似乎这是唯一的选择。
我正在尝试使用服务参考通过 C# 连接到 SSL SOAP 服务主机。 这是我的请求消息:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
<VsDebuggerCausalityData xmlns="http://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink">uIDPo/zwMmtdsVhFsAVDkQbiV/4AAAAA1zXtnc72UEm+4tlKzvCxsvN6OC2prvRIljIX4XzHKEYACQAA</VsDebuggerCausalityData>
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<u:Timestamp u:Id="_0">
<u:Created>2016-03-18T12:45:27.558Z</u:Created>
<u:Expires>2016-03-18T12:50:27.558Z</u:Expires>
</u:Timestamp>
<o:UsernameToken u:Id="uuid-2c7986ba-eee5-4411-90a9-a02b625c55ff-1">
<o:Username>MyUserName</o:Username>
<o:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">MyPlainPassword</o:Password>
</o:UsernameToken>
</o:Security>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<generateId xmlns="http://com.vedaadvantage/dp3/Enterprise/StandardTradeCreditCommercial/IndividualCommercialService"/>
</s:Body>
</s:Envelope>
这是我的服务发送给主机的消息。但是主机returns如下:
安全处理器无法在邮件中找到安全 header。这可能是因为消息是不安全的错误,或者是因为通信双方之间的绑定不匹配。如果服务配置为安全而客户端未使用安全性,则可能会发生这种情况。
这是我的配置文件:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<customBinding>
<binding name="myBinding">
<textMessageEncoding messageVersion="Soap11" />
<security authenticationMode="UserNameOverTransport"
messageSecurityVersion="WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10" >
</security>
<httpsTransport />
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="https://{URL}"
binding="customBinding"
bindingConfiguration="myBinding"
contract="ServiceReference2.MyService"
name="IndividualCommercialService" />
</client>
</system.serviceModel>
</configuration>
虽然当我通过 SOAPUI 或其他 HTTP Post 方法发送相同的 XML 时它工作正常。
我还提取并附加了证书和 user/pass,如下所示:
private static X509Certificate2 DownloadSslCertificate(string strDNSEntry)
{
X509Certificate2 cert = null;
using (TcpClient client = new TcpClient())
{
//ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
client.Connect(strDNSEntry, 443);
SslStream ssl = new SslStream(client.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null);
try
{
ssl.AuthenticateAsClient(strDNSEntry);
}
catch (AuthenticationException e)
{
//log.Debug(e.Message);
ssl.Close();
client.Close();
return cert;
}
catch (Exception e)
{
//log.Debug(e.Message);
ssl.Close();
client.Close();
return cert;
}
cert = new X509Certificate2(ssl.RemoteCertificate);
ssl.Close();
client.Close();
return cert;
}
}
private static void Main(string[] args){
var proxy = new MyService();
var uri = proxy.Endpoint.Address.Uri;
var cer = DownloadSslCertificate(uri.DnsSafeHost);
EndpointIdentity identity = EndpointIdentity.CreateDnsIdentity(cer.Subject.Replace("CN=", ""));
EndpointAddress address = new EndpointAddress(proxy.Endpoint.Address.Uri, identity);
proxy.Endpoint.Address = address;
proxy.ClientCredentials.UserName.UserName = "MyUserName";
proxy.ClientCredentials.UserName.Password = "MyPlainPassword";
proxy.ClientCredentials.ServiceCertificate.DefaultCertificate = cer;
proxy.HellowWorld();
}
我不确定我获取证书的方法是否正确,也不确定为什么 HTTP Post 有效但我的服务参考调用无效。
在此先感谢您的帮助。
干杯
尝试查看 WSDL(服务引用)以便首先查看隐藏文件 select 在解决方案资源管理器中显示所有文件。 您将在服务引用 Reference.svcmap -> Reference.cs 中看到,并在此文件中添加 ProtectionLevel = System.Net.Security.ProtectionLevel.Sign 如下图
[System.ServiceModel.ServiceContractAttribute(Namespace = "http://www.your.url/Service/", ConfigurationName = "Service.Service", ProtectionLevel = System.Net.Security.ProtectionLevel.Sign)]
应该对你有帮助。通常修改自动生成的代理是一个非常糟糕的主意,但似乎这是唯一的选择。