WCF.js Message Level Signature? Check.
Join the DZone community and get the full member experience.
Join For FreeThis is a very exciting moment for Wcf.js.
It now supports one of the WS-Security most common scenarios - x.509
digital signatures. This is the first WS-Security implementation ever in
javascript to support this. This implementation relies on xml-crypto on which I told you last time.
Look at any of the following Wcf bindings:
<wsHttpBinding> <binding name="NewBinding1"> <security> <message clientCredentialType="Certificate" /> </security> </binding> </wsHttpBinding>
<customBinding> <binding name="NewBinding0"> <textMessageEncoding /> <security authenticationMode="MutualCertificate" messageSecurityVersion="WSSecurity10..."> <secureConversationBootstrap /> </security> <httpTransport /> </binding> </customBinding>
Assume only signatures are used (no encryption):
[ServiceBehavior(ProtectionLevel=ProtectionLevel.SignOnly)]
Then a soap request would look like this:
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/" ... > <Header> <ws:Action>http://tempuri.org/IService/GetData</ws:Action> <ws:To>http://localhost:8888/</ws:To> <ws:MessageID>ca62b7d7-4f74-75ed-9f5c-b09b173f6747</ws:MessageID> <ws:ReplyTo> <ws:Address>...</ws:Address> </ws:ReplyTo> <o:Security> <u:Timestamp xmlns:wsu="..." wsu:Id="_1"> <u:Created>2012-05-25T12:18:38Z</u:Created> <u:Expires>2012-05-25T12:23:38Z</u:Expires> </u:Timestamp> <o:BinarySecurityToken ValueType="..." EncodingType="..." u:Id="sec_0"> MIIBxDCCAWI... </o:BinarySecurityToken> <Signature xmlns="http://www.w3.org/2000/09/xmldsig#"> <SignedInfo> <CanonicalizationMethod Algorithm="...xml-exc-c14n#" /> <SignatureMethod Algorithm="...rsa-sha1" /> <Reference URI="#_0"> <Transforms> <Transform Algorithm=".../xml-exc-c14n#" /> </Transforms> <DigestMethod Algorithm="...xmldsig#sha1" /> <DigestValue>fxQc0PEh2GHA43IXltm6gjbccsA=</DigestValue> </Reference> <Reference URI="#_1"> <Transforms> <Transform Algorithm=".../xml-exc-c14n#" /> </Transforms> <DigestMethod Algorithm="...xmldsig#sha1" /> <DigestValue>L+vrfEszbn2ZtXiWfNyDG8nM1e8=</DigestValue> </Reference> </SignedInfo> <SignatureValue>AcOb1KJHpyQnnChEZFEL7g+LEXnv...</SignatureValue> <KeyInfo> <o:SecurityTokenReference> <o:Reference URI="#sec_0" ValueType="..." /> </o:SecurityTokenReference> </KeyInfo> </Signature> </o:Security> </Header> <Body xmlns:wsu="..." wsu:Id="_0"> <GetData xmlns="http://tempuri.org/"> <value>123</value> </GetData> </Body> </Envelope>
You can now interoperate with such services from javascript using Wcf.js with this code:
var wcf = require('wcf.js') , fs = require("fs") , TextMessageEncodingBindingElement = wcf.TextMessageEncodingBindingElement , HttpTransportBindingElement = wcf.HttpTransportBindingElement , SecurityBindingElement = wcf.SecurityBindingElement , CustomBinding = wcf.CustomBinding , Proxy = wcf.Proxy var binding = new CustomBinding( [ new SecurityBindingElement({AuthenticationMode: "MutualCertificate"}) , new TextMessageEncodingBindingElement( {MessageVersion: "Soap11WSAddressing10"}) , new HttpTransportBindingElement() ]) var proxy = new Proxy(binding, "http://localhost:7171/Service") proxy.ClientCredentials.ClientCertificate.Certificate = fs.readFileSync("client.pem").toString() var message = "<Envelope xmlns='http://schemas.xmlsoap.org/soap/envelope/'>" + "<Header />" + "<Body>" + "<GetData xmlns='http://tempuri.org/'>" + "<value>123</value>" + "</GetData>" + "</Body>" + "</Envelope>" proxy.send(message, "http://tempuri.org/IService/GetData", function(message, ctx) { console.log(ctx) })
Note that a pem formatted certificate needs to be used. Wcf likes pfx formats more, so check out the instructions here on how to do the conversion.
You should also be aware that Wcf.js by default does no validate incoming signatures from the server. If you wish to validate them check out the sample here.
Opinions expressed by DZone contributors are their own.
Comments