Com C #, consumidor WCF SOAP que usa autenticação de texto simples WSSE?

Eu tenho um consumidor WCF SOAP que é implementado pelo Visual Studio 2012 de um WSDL. O WSDL foi gerado pelo PeopleTools. O object base é do tipo System.ServiceModel.ClientBase .

Eu preciso que a solicitação SOAP se pareça com:

     [plain text username goes here] [plain text password goes here]      Aren Cambre    

Aqui está o mais próximo que podemos obter:

   http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue urn:uuid:3cc3f2ca-c647-466c-b38b-f2423462c837  http://www.w3.org/2005/08/addressing/anonymous  http://[internal URL to soap listener]    http://schemas.xmlsoap.org/ws/2005/02/sc/sct http://schemas.xmlsoap.org/ws/2005/02/trust/Issue 256 FgMBAFoBAABWAwFQ9IhUFGUO6tCH+0baQ0n/3us//MMXzQA78Udm4xFj5gAAGAAvADUABQAKwBPAFMAJwAoAMgA4ABMABAEAABX/AQABAAAKAAYABAAXABgACwACAQA=    

Você notará dois problemas:

  • Nenhuma credencial WSSE de texto simples. Passa uma forma binária das credenciais que o serviço não usará.
  • A autenticação está no Body , não no Header .
  • A solicitação omite InputParameters .

Aqui está o código essencial do 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); 

Não há segurança de camada HTTP e o transporte é criptografado por SSL. A autenticação é baseada somente na mensagem SOAP.

    Essa é a solicitação para o token WS-SecureConversation. Ele é usado pelo WSHttpSecurity por padrão, a menos que você altere sua propriedade EstablishSecurityContext para false . Use esta binding em vez disso:

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

    Ele usará o SOAP 1.1 com o token UserName e exigirá o transporte HTTPS.

    Editar:

    Para testar sem HTTPS, tente usar essa binding personalizada:

     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); 

    Isso me parece como wsHttpBindings com segurança de transporte usando autenticação de senha básica de nome de usuário.

    Essas linhas parecem erradas para mim:

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

    Aqui está como eu esperaria ver isso configurado no seu aplicativo ou web.config

                 

    Então o código ficaria assim:

     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); 

    Pode ser melhor explicado aqui -> http://msdn.microsoft.com/pt-br/library/ms733775.aspx