对于c#,使用WSSE纯文本身份验证的WCF SOAP消费者

本文关键字:身份验证 WCF SOAP 消费者 文本 使用 WSSE 对于 | 更新日期: 2023-09-27 17:52:57

我有一个由Visual Studio 2012从WSDL实现的WCF SOAP消费者。WSDL是由PeopleTools生成的。基本对象的类型为System.ServiceModel.ClientBase

我需要SOAP请求类似:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sch="http://xmlns.oracle.com/Enterprise/Tools/schemas">
    <soapenv:Header>
        <wsse:Security soap:mustUnderstand="1" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
            <wsse:UsernameToken>
                <wsse:Username>[plain text username goes here]</wsse:Username>
                <wsse:Password>[plain text password goes here]</wsse:Password>
            </wsse:UsernameToken>
        </wsse:Security>
    </soapenv:Header>
    <soapenv:Body>
        <sch:InputParameters>
            <Last_Name>Aren</Last_Name>
            <First_Name>Cambre</First_Name>
        </sch:InputParameters>
    </soapenv:Body>
</soapenv:Envelope>

这是我们能得到的最接近的:

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
    <s:Header>
        <a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue</a:Action>
        <a:MessageID>urn:uuid:3cc3f2ca-c647-466c-b38b-f2423462c837</a:MessageID>
        <a:ReplyTo>
            <a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
        </a:ReplyTo>
        <a:To s:mustUnderstand="1">http://[internal URL to soap listener]</a:To>
    </s:Header>
    <s:Body>
        <t:RequestSecurityToken Context="uuid-7db82975-2b22-4236-94a1-b3344a0bf04d-1" xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust">
            <t:TokenType>http://schemas.xmlsoap.org/ws/2005/02/sc/sct</t:TokenType>
            <t:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</t:RequestType>
            <t:KeySize>256</t:KeySize>
            <t:BinaryExchange ValueType=" http://schemas.xmlsoap.org/ws/2005/02/trust/tlsnego" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">FgMBAFoBAABWAwFQ9IhUFGUO6tCH+0baQ0n/3us//MMXzQA78Udm4xFj5gAAGAAvADUABQAKwBPAFMAJwAoAMgA4ABMABAEAABX/AQABAAAKAAYABAAXABgACwACAQA=</t:BinaryExchange>
        </t:RequestSecurityToken>
    </s:Body>
</s:Envelope>

你会注意到两个问题:

  • 没有明文WSSE凭证。传递服务不会使用的凭证的二进制形式。
  • 认证是Body,不是Header
  • 请求忽略InputParameters
下面是基本的c#代码:
var service = new ServiceWithBizarreNameFromPeoplesoft();
if (service.ClientCredentials == null)
   throw new NullReferenceException();
service.ClientCredentials.UserName.UserName = "test";
service.ClientCredentials.UserName.Password = "password";
var binding = new WSHttpBinding(SecurityMode.TransportWithMessageCredential) {Security = new WSHttpSecurity()};
service.Endpoint.Binding = binding;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
binding.Security.Mode = SecurityMode.Message;
var input = new InputParameters { Last_Name = "Cambre", First_Name = "Aren" };
var returnData = service.BizarrePeopleSoftNameForMethod(input);

没有HTTP层安全,传输是ssl加密的。身份验证仅基于SOAP消息。

对于c#,使用WSSE纯文本身份验证的WCF SOAP消费者

这是对WS-SecureConversation令牌的请求。默认情况下由WSHttpSecurity使用,除非您将其EstablishSecurityContext属性更改为false。请使用此绑定:

var binding = new BasicHttpBinding(BasicHttpSecurityMode.TransportWithMessageCredential);    
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
binding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;

它将使用带有UserName令牌的SOAP 1.1,并且需要HTTPS传输。

编辑:

对于没有HTTPS的测试,尝试使用以下自定义绑定:
var securityElement = SecurityBindingElement.CreateUserNameOverTransportBindingElement();
securityElement.AllowInsecureTransport = true;
var encodingElement = new TextMessageEncodingBindingElement(MessageVersion.Soap11, Encoding.UTF8);
var transportElement = new HttpTransportBindingElement();
var binding = new CustomBinding(securityElement, encodingElement, transportElement);

这看起来像wsHttpBindings与传输安全使用基本的用户名密码身份验证。

我看这些行不对:

binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
binding.Security.Mode = SecurityMode.Message;

我希望在你的应用程序或web.config中看到这样的配置

<bindings>
  <wsHttpBinding>
    <binding name="ws" >
      <security mode="Transport">
        <transport clientCredentialType="Basic" proxyCredentialType="Basic" />
      </security>
    </binding>
  </wsHttpBinding>
</bindings>
<client>
  <endpoint address="http://www.bla.com/webservice" binding="basicHttpBinding" contract="bla.IService" name="ws" />
</client>

那么代码看起来像这样:

var service = new GeneratedProxyClient("basic");
service.ClientCredentials.UserName.UserName = "test";
service.ClientCredentials.UserName.Password = "password";
var input = new InputParameters { Last_Name = "Cambre", First_Name = "Aren" };
var returnData = service.BizarrePeopleSoftNameForMethod(input);

可能在这里更好地解释--> http://msdn.microsoft.com/en-us/library/ms733775.aspx