How can I pass a username/password in the header to a SOAP WCF Service How can I pass a username/password in the header to a SOAP WCF Service asp.net asp.net

How can I pass a username/password in the header to a SOAP WCF Service


The answers above are so wrong! DO NOT add custom headers. Judging from your sample xml, it is a standard WS-Security header. WCF definitely supports it out of the box. When you add a service reference you should have basicHttpBinding binding created for you in the config file. You will have to modify it to include security element with mode TransportWithMessageCredential and message element with clientCredentialType = UserName:

<basicHttpBinding>  <binding name="usernameHttps">    <security mode="TransportWithMessageCredential">      <message clientCredentialType="UserName"/>    </security>  </binding></basicHttpBinding>

The config above is telling WCF to expect userid/password in the SOAP header over HTTPS. Then you can set id/password in your code before making a call:

var service = new MyServiceClient();service.ClientCredentials.UserName.UserName = "username";service.ClientCredentials.UserName.Password = "password";

Unless this particular service provider deviated from the standard, it should work.


There is probably a smarter way, but you can add the headers manually like this:

var client = new IdentityProofingService.IdentityProofingWSClient();using (new OperationContextScope(client.InnerChannel)){    OperationContext.Current.OutgoingMessageHeaders.Add(        new SecurityHeader("UsernameToken-49", "12345/userID", "password123"));    client.invokeIdentityService(new IdentityProofingRequest());}

Here, SecurityHeader is a custom implemented class, which needs a few other classes since I chose to use attributes to configure the XML serialization:

public class SecurityHeader : MessageHeader{    private readonly UsernameToken _usernameToken;    public SecurityHeader(string id, string username, string password)    {        _usernameToken = new UsernameToken(id, username, password);    }    public override string Name    {        get { return "Security"; }    }    public override string Namespace    {        get { return "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"; }    }    protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)    {        XmlSerializer serializer = new XmlSerializer(typeof(UsernameToken));        serializer.Serialize(writer, _usernameToken);    }}[XmlRoot(Namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd")]public class UsernameToken{    public UsernameToken()    {    }    public UsernameToken(string id, string username, string password)    {        Id = id;        Username = username;        Password = new Password() {Value = password};    }    [XmlAttribute(Namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd")]    public string Id { get; set; }    [XmlElement]    public string Username { get; set; }    [XmlElement]    public Password Password { get; set; }}public class Password{    public Password()    {        Type = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText";    }    [XmlAttribute]    public string Type { get; set; }    [XmlText]    public string Value { get; set; }}

I have not added the Nonce bit to the UsernameToken XML, but it is very similar to the Password one. The Created element also needs to be added still, but it's a simple [XmlElement].


Adding a custom hard-coded header may work (it also may get rejected at times) but it is totally the wrong way to do it. The purpose of the WSSE is security. Microsoft released the Microsoft Web Services Enhancements 2.0 and subsequently the WSE 3.0 for this exact reason. You need to install this package (http://www.microsoft.com/en-us/download/details.aspx?id=14089).

The documentation is not easy to understand, especially for those who have not worked with SOAP and the WS-Addressing. First of all the "BasicHttpBinding" is Soap 1.1 and it will not give you the same message header as the WSHttpBinding. Install the package and look at the examples. You will need to reference the DLL from WSE 3.0 and you will also need to setup your message correctly. There are a huge number or variations on the WS Addressing header. The one you are looking for is the UsernameToken configuration.

This is a longer explanation and I should write something up for everyone since I cannot find the right answer anywhere. At a minimum you need to start with the WSE 3.0 package.