代码之家  ›  专栏  ›  技术社区  ›  Eduardo Arenas Prada

具有传输和消息安全性的WCF绑定

  •  3
  • Eduardo Arenas Prada  · 技术社区  · 11 年前

    我正在一个大项目中工作,该项目广泛利用 WCF公司 用于不同类型的通信。作为新需求的一部分,我们需要与 肥皂 由第三方开发的Web服务。他们的服务是用Java开发的,有两个安全要求:

    1. 它需要 BASIC身份验证 过度运输和

    2. 消息必须是 使用X509证书签名(未加密) 使用 WS安全(OASIS) 不可否认性标准。

    我遇到的问题是WCF提供的绑定允许使用传输或消息安全性,但是 不是两者同时出现 因此,我可以对SOAP消息进行签名,也可以发送BASIC身份验证凭据,但到目前为止,我还不能根据需要同时执行这两项操作。

    几天来,我一直在试图找到一个解决方案,到目前为止,我得出的结论是,我最好的办法可能是以编程方式进行自定义绑定。使用几个来源,这就是我现在所拥有的:

    var b = new CustomBinding();
    
    var sec = (AsymmetricSecurityBindingElement)SecurityBindingElement.CreateMutualCertificateBindingElement(MessageSecurityVersion.WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10);
    
    UserNameSecurityTokenParameters tokenParamenters = new UserNameSecurityTokenParameters();
    tokenParamenters.InclusionMode = SecurityTokenInclusionMode.AlwaysToRecipient;
    tokenParamenters.RequireDerivedKeys = false;
    
    b.Elements.Add(sec);
    b.Elements.Add(new TextMessageEncodingBindingElement(MessageVersion.Soap11, Encoding.UTF8));
    b.Elements.Add(new HttpsTransportBindingElement());
    
    WSClient svc = new WSClient(b, new EndpointAddress(new Uri("https://serviceurl.com/SoapWS"), new DnsEndpointIdentity("CertificateIdentity"), new AddressHeaderCollection()));
    svc.ClientCredentials.UserName.UserName = "username";
    svc.ClientCredentials.UserName.Password = "password";
    
    svc.ClientCredentials.ClientCertificate.Certificate = new X509Certificate2("Certificate.p12", "password");
    svc.ClientCredentials.ServiceCertificate.DefaultCertificate = new X509Certificate2("Certificate.p12", "password");
    svc.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.None;
    
    string resp = svc.DoSomething();
    

    虽然这似乎是用证书对消息进行签名(还不能完全检查),但基本的身份验证部分并没有发生。来自服务器的响应是:

    HTTP请求未经授权,客户端身份验证方案为“匿名”。从服务器收到的身份验证标头为“Basic realm=“realm”。

    任何关于如何使用BASIC身份验证使此绑定通过传输进行身份验证的见解都将非常有帮助。提前谢谢。

    附言:请注意,我无法控制我试图与之通信的网络服务。

    1 回复  |  直到 11 年前
        1
  •  2
  •   Yaron Naveh    11 年前

    配置https传输通道:

    HttpsTransportBindingElement h = new HttpTransportBindingElement();
    h.AuthenticationScheme = AuthenticationSchemes.Digest;
    h.realm = ...
    

    如果你遇到麻烦,我建议你先设置一个workign传输基本http绑定,这样你就可以看到你通过服务器https传输(你应该会得到一个soap错误b/c缺少签名)。