Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

WCF.js Message Level Signature? Check.

DZone's Guide to

WCF.js Message Level Signature? Check.

· Web Dev Zone
Free Resource

Start coding today to experience the powerful engine that drives data application’s development, brought to you in partnership with Qlik.

This 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.

Create data driven applications in Qlik’s free and easy to use coding environment, brought to you in partnership with Qlik.

Topics:

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}