Skip to content

Instantly share code, notes, and snippets.

@neilgaietto
Created October 4, 2019 17:50
Show Gist options
  • Save neilgaietto/d04d665d7cab7e8b414c498099bb6836 to your computer and use it in GitHub Desktop.
Save neilgaietto/d04d665d7cab7e8b414c498099bb6836 to your computer and use it in GitHub Desktop.
WSS: SOAP Message Security Header for .NET
public class Example
{
public WebServiceResponseObject CallWebService()
{
var client = new YourWebserviceClient();
try
{
client.Open();
using (OperationContextScope scope = new OperationContextScope(client.InnerChannel))
{
MessageHeaders messageHeadersElement = OperationContext.Current.OutgoingMessageHeaders;
messageHeadersElement.Add(new SecurityHeader("username", "password"));
var result = client.DoThing();
return result;
}
}
catch (Exception ex)
{
// show the error
throw;
}
finally
{
client.Close();
}
}
}
public class SecurityHeader : System.ServiceModel.Channels.MessageHeader
{
public string username;
public string password;
public string passwordDigest;
public string created;
public string nonce;
public SecurityHeader(string username, string password)
{
string noncePhrase = Guid.NewGuid().ToString();
var created = System.DateTime.UtcNow.ToString("o");
this.username = username;
this.password = password;
this.created = created;
this.nonce = ToBase64(noncePhrase);
this.passwordDigest = GetHashedString(noncePhrase + created + password);
}
protected override void OnWriteStartHeader(System.Xml.XmlDictionaryWriter writer, System.ServiceModel.Channels.MessageVersion messageVersion)
{
writer.WriteStartElement("o", Name, Namespace);
writer.WriteXmlnsAttribute("o", Namespace);
}
protected override void OnWriteHeaderContents(System.Xml.XmlDictionaryWriter writer, System.ServiceModel.Channels.MessageVersion messageVersion)
{
var xml =
"<wsse:UsernameToken wsu:Id=\"" + this.username + "\" xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\" xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\">" +
"<wsse:Username>" + this.username + "</wsse:Username>" +
"<wsse:Password Type=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest\">" + this.passwordDigest + "</wsse:Password>" +
"<wsse:Nonce>" + this.nonce + "</wsse:Nonce>" +
"<wsu:Created>" + this.created + "</wsu:Created>" +
"</wsse:UsernameToken>";
writer.WriteRaw(xml);
}
protected string GetHashedString(string phrase)
{
var hasher = new SHA256CryptoServiceProvider();
byte[] hashedDataBytes = hasher.ComputeHash(Encoding.UTF8.GetBytes(phrase));
return Convert.ToBase64String(hashedDataBytes);
}
protected string ToBase64(string phrase)
{
byte[] hashedDataBytes = Encoding.UTF8.GetBytes(phrase);
return Convert.ToBase64String(hashedDataBytes);
}
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"; }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment