David Rutter


Welcome to my Blog. I'm the CTO for Tag: In this blog I will be sharing some of our business successes and technical challenges. Where it is useful I will get technical and share code snippets. Our main platform is SQL Server, Flex and ColdFusion. I'm also experienced in C++, Java and ASP/.NET.

ColdFusion 9, Apache, Xampp

Tuesday, February 2nd, 2010

Running Apache with ColdFusion should be relatively simple; install ColdFusion and Apache, and then run the Web Server Configuration tool. I tried this recently with the developer version of ColdFusion 9 and got an unhelpful error about the jndi.properties file. I’ve also heard fro a couple of other developers having similar issues.

Rather then trying to figure out whats wrong with the ColdFusion install, you can set this up manually. On the following site, the author has detailed how to do this step by step: http://www.codecurry.com/2010/01/coldfusion-manual-configuration-issues.html. It takes only a few minutes, and is simpler than it looks.

There are a few minor things in the steps to watch out for. You need to set the jrun proxy server property called ‘deactivated’ to false (the article says true). There are some minor typos with white space and numbering (so if configuring for apache use ‘1′ for everything where you see a ‘2′).

These instructions were designed for a standard Apache install; if you have an Xampp install (to get a lamp stack with mysql php etc), the above instructions will also work for xampp, provided you modify the pathnames to the xampp apache server.

BTW  Whilst Xampp is an easy way to get a flexible development setup, it is not something I would consider for a production environment.

ColdFusion in the Enterprise, and Integration Technologies: SOTR 2008

Tuesday, June 16th, 2009

Attached is are two slightly abbreviated presentations that I did last year at SOTR (2008). The first was ColdFusion in the Enterprise, and covers

  • Scalability
  • Business Continuity
  • Single Sign On
  • Auditing
  • Localization, Globalization

The second, ColdFusion and Java, looks at integration technologies

  • JSP Tag Libraries
  • Java Libraries
  • WebServices
  • XML

And illustrates these concepts using the following

  • Globalization
  • iText
  • LiveCycle ES
  • SSO

ColdFusion Security and SOTR

Tuesday, June 9th, 2009

Scotch on the Road was a great concept; bringing the ColdFusion to the major cities in the UK at a very affordable price.

I spoke at the London event on ColdFusion security. The screen I had wasn’t really big enough for the room, so for those wanting to see the slides, I’ve attached a slightly  abridged version, without the creds.

The presentation is mainly about ColdFusion security, but also briefly covers the bigger picture, including security standards, infrastructure, and the development process.[SOTR ColdFusion Security]

Acrobat 9

Sunday, June 8th, 2008

Adobe have released the public beta of Acrobat 9 and Acrobat 9 Reader. There are three great new features very relevant to the work we do.

  • Acrobat 9 has the flash engine built in. Flash and therefore Flex, can be embedded into PDFs. 
    This means there is now a third way to distribute flex applications: by emailing PDF files.
  • Video can also be embedded in a PDF: both H264 and flv formats.
  • And finally PDF annotation support has been added for both flash and video.

For a media  company like Tag: that has large TV and interactive capabilities, this makes the PDF format even more compelling and useful.

Scotch Rocked

Sunday, June 8th, 2008

This years ‘Scotch on the Rocks’ European ColdFusion conference had a great line up of speakers with some excellent presentations on ColdFusion, Flex, AIR and related technologies.

Adobe were there in strength. We had some good presentations from their specialists including Ben Forte and Adam Lehman. Some of the ColdFusion management team were also there, which gave me the opportunity to get some time with Jason Delmore, the ColdFusion Product Manger, and Kristen Schofield the ColdFusion Product Marketing Manger.

Scotch is an independent, developer lead, ColdFusion conference. The speakers make themselves available; they don’t hide away in speaker only facilities. Also, the other ColdFusion companies, Railo and Blue Dragon, were in attendance. The most significant contribution was the Railo announcement to open source with JBoss. The JBoss link adds enormous credibility and potential to their platform.

I gave 2 talks at Scotch on using ‘ColdFusion in the Enterprise’ and ‘ColdFusion Integration with Java, XML and WebServices’. Both talks were well attended and I was very pleased with the feedback I got.

I hope more of you take the opportunity to go next year; it is the best European ColdFusion conference, both for the depth and breadth of the presentations and the value for money.

SAML, SSO and ColdFusion

Monday, May 12th, 2008

Overview

The following post is intended as an overview of how a clients IT department could integrate their intranet with our CMD system to provide a seamless single sign on. There are commercial systems that can do this and we have integrated with some of them. The following shows how to use the open source Apache XMLSecurity library to the same effect.

For an overview of SSO and SAML see my earlier posting. In this post I will illustrate an implementation using the SAML Post Profile, the Apache XML Security library and ColdFusion. (Since the Apache library is a java library, the JSP/java code is almost identical). There are two parts: the creation of the SAML on the intranet server (IdP) and the interpretation of this by an external service, or to use the correct terminology, service provider (SP).

Configuring the Idp

This article assumes that you have ColdFusion 8. Alternatively you could run Tomcat and use JSP although the syntax is different, the library calls are the same.

This implementation uses the Apache XML security library. Download and place in the WEB-INF/cfusion/lib directory for ColdFusion (for java into your applications lib directory), You probably already have many of the jar files and just need serializer.jar and xmlsec-nnn.jar, where nnn is the current version number.

Creating the SAML on the IdP

The starting point is a SAML assertion from the previous article. We need to add some real user data and time information. The users identity and other information to embed in the SAML would come from Active Directory, LDAP etc. For this example I’ve hard coded some values.

<cfscript>
    ssouser=StructNew();
    ssouser[”email”]=”user@tagworldwide.com”;
    nowDateTime =
        #DateFormat(DateConvert(’local2utc’,
          Now()),’YYYY-MM-DDT’)#
        & #TimeFormat(DateConvert(’local2utc’,
          Now()),’HH:mm:SSZ’)#;
    nowDateTimePlus1 =
        #DateFormat(DateConvert(’local2utc’,
          DateAdd(’n',1,Now())),’YYYY-MM-DDT’)#
        & #TimeFormat(DateConvert(’local2utc’,
          DateAdd(’n',1,Now())),’HH:mm:SSZ’)#;
</cfscript>

The CFXML tag provides an easy way to populate the SAML

<cfoutput>
<cfxml variable=”samlAssertionXML”>
<samlp:Response
  xmlns:ds=http://www.w3.org/2000/09/xmldsig#chr(35)#
  xmlns:saml=”urn:oasis:names:tc:SAML:1.0:assertion” 
  xmlns:samlp=”urn:oasis:names:tc:SAML:1.0:protocol” 
  IssueInstant=”#nowDateTime#”
  MajorVersion=”1″ MinorVersion=”1″ 
  Recipient=”http://externalService/sso/post/
  ResponseID=”#CreateUUID()#”>
    <samlp:Status>
        <samlp:StatusCode Value=”samlp:Success”/>
    </samlp:Status>
    <saml:Assertion
        xmlns:saml=”urn:oasis:names:tc:SAML:1.0:assertion”
        AssertionID=”#AssertionID#”
        IssueInstant=”#nowDateTime#”
        Issuer=”#issuer#” MajorVersion=”1″
        MinorVersion=”1″>
        <saml:Conditions NotBefore=”#nowDateTime#”
            NotOnOrAfter=”#nowDateTimePlus1#”>
            <saml:AudienceRestrictionCondition>
                <saml:Audience>
                  http://intranet/IdP
                </saml:Audience>
            </saml:AudienceRestrictionCondition>
        </saml:Conditions>
        <saml:AuthenticationStatement 
           AuthenticationInstant=”2007-11-04T13:52:42Z”>
           <saml:Subject>
             <saml:NameIdentifier>#ssouser.id#
             </saml:NameIdentifier>
           </saml:Subject>
        </saml:AuthenticationStatement>
        <saml:AttributeStatement>
         <saml:Attribute AttributeName=”emailaddress”>
         <saml:AttributeValue>#ssouser.email#
         </saml:AttributeValue> 
         </saml:Attribute>
         <saml:Attribute AttributeName=”givenname”>
         <saml:AttributeValue>
             #ssouser.givenname#
           </saml:AttributeValue> 
         </saml:Attribute>
         <saml:Attribute AttributeName=”surname”>  
         <saml:AttributeValue>
         #ssouser.surname#
         </saml:AttributeValue> 
         </saml:Attribute>
        </saml:AttributeStatement>
    </saml:Assertion>
</samlp:Response>
</cfxml>
</cfoutput>

The above uses an authentication statement for the users identity and attribute statements for additional attributes e.g. users full name, email address etc. The standard doesn’t define which attributes are used. It allows namespace attributes to be used, allowing complete flexibility.

To add a signature element, we use the XMLSecurity library. The ColdFusion variables need coaxing to extract the right java objects. The last line does the actual insertion of a signature element into the SAML.

<cfscript>
samlAssertionElement = 
  samlAssertionXML.getDocumentElement();
samlAssertionDocument =
  samlAssertionElement.GetOwnerDocument();
samlAssertion = samlAssertionDocument
  .getFirstChild();
SignatureSpecNS = CreateObject(”Java”,
  “org.apache.xml.security.utils.Constants”)
  .SigSpecNS;
Init = CreateObject(”Java”, 
   “org.apache.xml.security.Init”).Init().init();
XMLSignatureClass = CreateObject(”Java”, 
   “org.apache.xml.security.signature.XMLSignature”);
sigType =
   XMLSignatureClass.ALGO_ID_SIGNATURE_RSA_SHA1;
signature = XMLSignatureClass
   .init(samlAssertionDocument, 
    javacast(”string”,”"), sigType); 
samlAssertionElement
  .insertBefore(signature 
  .getElement(),samlAssertion.getFirstChild());

</cfscript>

Note that the signature is inside the the XML that we are signing; this is known as an enveloped signature. The following is needed by the XMLSecurity library to define that we will be using an enveloped signature.

TransformsClass = CreateObject(”Java”,
“org.apache.xml.security.transforms.Transforms”);
transformEnvStr =  
TransformsClass.TRANSFORM_ENVELOPED_SIGNATURE;
transformOmitCommentsStr =
TransformsClass.TRANSFORM_C14N_EXCL_OMIT_COMMENTS;
transforms = TransformsClass
.init(samlAssertionDocument
transforms.addTransform(transformOmitCommentsStr);
transforms.addTransform(transformEnvStr);

To sign the SAML, we need a certificate. A self self certificate can be used. Typically issuer signed certificates are used, and for this the cheapest certificate from Thawte etc is sufficient. Java typically stores these in a key store. You can follow one of the numerous guides to doing this via the command line or use Portecle which is very easy to use. The code to extract a certificate from a key store is as follows

ksfile = CreateObject(”Java”, “java.io.File”)
  .init(storepath);
inputStream = CreateObject(”Java”,
  “java.io.FileInputStream”)
  .init(ksfile);
KeyStoreClass = CreateObject(”Java”
  , “java.security.KeyStore”);        
ks = KeyStoreClass.getInstance(”JKS”); 
ks.load(inputStream,”sso”); 
key = ks.getKey(”sso”,keypw.toCharArray());
cert = ks.getCertificate(certAlias);
publickey = cert.getPublicKey();

We now need to add a digest, signature and key information.

signature.addDocument(”#chr(35)##AssertionID#”
  , transforms);
signature.addKeyInfo(cert);
signature.addKeyInfo(publickey);
signature.sign(key);

In this example we have signed the whole response. You will see examples on the web where first the saml assertion is signed, and then in addition the response is signed as well. This isn’t required when the assertion and response are created at the same time.

Finally, encode this into a HTML page that will do a post to the SP.

<html>
    <body onload=”document.forms[0].submit()”>
        <form action=
http://ServiceProvider/SSO/POST/” method=”post”>
        <input type=”hidden” name=”SAMLRequest”
        value=’#BinaryEncode(
           CharsetDecode(
           samlAssertionXML,”utf-8″)
           ,”Base64″)#’/>
        </form>
    </body>
</html>

Interpreting the XML on the External Service (SP)

On the Service Provider, we do everything in reverse.

First extract the SAML, parse the XML, and verify the signature. There are a few lines of code to set up the various java objects correctly; the last line does the work.

xmlResponse=CharsetEncode(
  BinaryDecode(form.SAMLRequest,”Base64″)
  ,”utf-8″);
docElement= XmlParse(variables.xmlResponse)
  .getDocumentElement();
SignatureConstants=CreateObject(
  “Java”, “org.apache.xml.security.utils.Constants”);
SignatureSpecNS=SignatureConstants.SignatureSpecNS; 
xmlSignatureClass = CreateObject(”Java”,
  “org.apache.xml.security.signature.XMLSignature”);
xmlSignature = xmlSignatureClass 
  .init(docElement.getElementsByTagNameNS
  (SignatureSpecNS,”Signature”)
  .item(0),”");
keyInfo=xmlSignature.getKeyInfo();
X509CertificateResolverCN = 
  “org.apache.xml.security.keys.keyresolver
  .implementations.X509CertificateResolverClass”).
keyResolver=CreateObject(”Java”,
   X509CertificateResolverCN)
  .init();
keyInfo.registerInternalKeyResolver(keyResolver);
x509cert = keyInfo.getX509Certificate();

isValid = xmlSignature.checkSignatureValue(x509cert);

Assuming the SAML has been correctly signed, we now need to establish that the request is from an approved source, is in the right time frame and isn’t a repeat. Finally extract the users identity.

ssoissuer = getSingleValue(XPathIssuer);
conditions = getSingleValue(XPathConditions);
beforeDate = DateConvertISO8601
  (conditions.XmlAttributes.NotBefore, 0);
afterDate = DateConvertISO8601
  (conditions.XmlAttributes.NotOnOrAfter, afterwindow);
certificate = getSingleValue
  (XPathCertificates).XmlText;
reference = getSingleValue(XPathUniqueReference);

// Verify Validity Info
// …

   // Extract User
   ssouser =  getSingleValue(XPathNameIdentifier).xmltext;

Much of the additional code for validity, verifying whether its a new or existing user etc will be very much application dependant.

The extras

The code above uses the function DateConvertISO8601, an implementation of this from David Satz can be found on cflib. The function getSingleValue is a wrapper around XMLSearch.

Finally, the class org.apache.xml.security.Init has an init initializer method that clashes with the ColdFusion init method; in CF 7 you need to call it via java introspection as in the following snippet (thanks to Jon for the correction on this):

InitClass = CreateObject(”Java”,
     “org.apache.xml.security.Init”);
emptyArray = ArrayNew(1);
initMethod=InitClass.GetClass()
  .GetMethod(”init”,emptyArray);
initMethod.invoke(Init,emptyArray);

<cffunction name=”getSingleValue” output=”false”
   access=”public” returntype=”ANY”>
   <!— Expects an array of values to be returned
   from XML data, but only returns the first one —>
   <cfargument name=”xpath” required=”true”>
   <cfargument name=”reqAttrib” required=”No”
     type=”boolean” default=”true”>
    <cfset values=
        XmlSearch(variables.xmlResponse,
        arguments.xpath)>
        <cfif reqAttrib >
         <cfif ArrayLen(values) EQ 0>
           <cfthrow type=”saml”
           message=”Error: No value for: #xpath#”>
        </cfif>
        </cfif>
        <cfif isArray(values)>
            <cfreturn values[1]>
        <cfelse>
            <cfreturn values >
        </cfif>
</cffunction>

More Reading

This PDF has a very clear java implementation. Phil Duba has a set of well written SAML articles on his blog. This uses a wrapper round a java implementation. You may also need to know about the differences between SAML1.1 and SAML 2.0: see saml.xml.org.

SSO with SAML

Wednesday, April 16th, 2008

Overview

We frequently get requests from clients to integrate our Tag:CMD system which a SAAS offering (Software As A Service) with their internal LDAP system. The purpose of the Blog is to describe how we approach SSO (Single Sign On)and to illustrate how it can be implemented.

The first part of the post is generic to SSO, after which, in a second post, I will illustrate an implementation using the SAML Post Profile, the Apache XML Security library and ColdFusion. (Since the Apache library is a java library, the java code is almost identical).

SSO has  a number of advantages:

  • Users want a single account and password to work on all their work systems
  • Reduces user maintenance in the application
  • Ensures user information is kept up to date
  • When users change employment their accounts are automatically deactivated

What is sometimes harder to appreciate is that its not as simple as calling their LDAP server. When evaluating a SSO solution we are looking for some key elements:

  • The clients server does the authentication to avoid
    • storing of users passwords in our database
    • forwarding of users passwords though our servers
  • The clients server sends us the following information
    • Users identity
    • Basic information about the user (e.g. Name, email etc)
    • Servers identity
    • Time stamp
  • Signatures, certificates and/or secret keys are used to protect against
    • Modification of the information
    • Replay of the information at a later point in time 
  • The system is decoupled so we don’t need a dedicated VPN or back channel to the users server

There are a number of standards for SSO including

  • OASIS: SAML
  • Liberty: ID-FF
  • OpenID
  • Etc

SAML

Many of these use SAML to exchange information. SAML looks complicated and verbose. Essentially its made up of a set of statements, called SAML Assetions. To this we add elements to provide identity and ensure the statements haven’t been modified.

The following illustrates the basic elements. Start with the user identity

<saml:AuthenticationStatement>
    <saml:Subject>
        <saml:NameIdentifier>DavidRutter</saml:NameIdentifier>
    </saml:Subject>
</saml:AuthenticationStatement>

This is incorporated into what is called a SAML Assertion; we can add time properties to this to define its validity period.

<saml:Assertion IssueInstant="2007-11-04T14:04:24Z">
    <saml:Conditions
        NotBefore="2007-11-04T13:59:24Z"
        NotOnOrAfter="2007-11-04T14:14:24Z"/>
    <saml:AuthenticationStatement>
      <saml:Subject>
        <saml:NameIdentifier>DavidRutter</saml:NameIdentifier>
      </saml:Subject>
    </saml:AuthenticationStatement>
</saml:Assertion>

The next steps involve signing the SAML assetions to verify who they came from and that they haven’t been tampered with. There are 3 parts to this:

  • The signed information
  • A signature of the signed information
  • A keyinfo to describe what was used for the signature

We create a digest of the SAML assetions using the secure SHA algorithm so ensure the SAML can’t be modified

<ds:SignedInfo>
    <ds:DigestValue>/UlguevI2sppqGHnuZQV</ds:DigestValue>
</ds:SignedInfo>

Sign the digest to prove the identity. The signing is done using the private key of a certificate.

<ds:SignatureValue>
ID0Pr3EMyqvLilnZ0YNzt3z8GEyz6029V11rq
</ds:SignatureValue>

We add a keyinfo section to identify what was used for the signature. This can be the actual certificate.

<ds:KeyInfo>
    <ds:X509Data>
        <ds:X509Certificate>MIIC6jCCAd</ds:X509Certificate>
   </ds:X509Data>
</ds:KeyInfo>

Putting the signature altogether looks something like this:

<ds:Signature>
  <ds:SignedInfo>
    <ds:DigestValue>/UlguevI2sppqGHnuZQV</ds:DigestValue>
  </ds:SignedInfo> 
  <ds:SignatureValue>
ID0Pr3EMyqvLilnZ0YNzt3z8GEyz6029V11rq
  </ds:SignatureValue>
  <ds:KeyInfo>
    <ds:X509Data>
        <ds:X509Certificate>MIIC6jCCAd…</ds:X509Certificate>
    </ds:X509Data> 
  </ds:KeyInfo>
</ds:Signature>

 

Profiles

Assuming we have a library capable of creating the SAML, the next part is to define how the user, the system creating the SAML (the issuer or IdP) and the system receiving the SAML (the service provider or SP)  interact.

There are a number of different profiles, the simplest architecturally is the Browser Post Profile.

  • User goes to an intranet site and is authenticated.
    (either automatically via, or using a username/password)
  • User clicks on a link to take them indirectly to the external service
    e.g. http://intranet/SamlRedirect?goto=ExternalServiceUrl
  • The link first goes to an intranet hosted page which generates the SAML, does a 64bit encoding, and generates a
    a HTML page with a javascript redirect to the external service
  • The users browser will automatically do a HTP POST of the SAML to the external service
  • External service decodes and verifies the SAML, and logs in the user automatically.

The html will look something like the following:

<body onload="saml.submit()" >
<form name="saml"
    method="post"action=http://serviceProvider/SSO/POST/ …>
    <input type="hidden" name="SAMLResponse" value="response" />
    …
    <input type="submit" value="Submit" />
  </form>
</body>

Implementation

This will be covered in a second post on how to do the encoding and decoding in Java and ColdFusion.

Links

See this wikipedia article for more information and links

Tag: Releases Adobe AIR Application

Tuesday, March 25th, 2008

Today marks the release of our first AIR application. The application is being rolled out to the first users today, following the successful completion of UAT. The application will be rolled out gradually over the next few weeks to a sales team of about 700 who will be using the application on their laptops nationwide within the UK.

The application forms part of a larger innovative project that will see our client radically improve their online offerings. So although I would like to say more and provide links and show off what we have done, I can’t.

Suffice to say AIR has done a great job of enabling web designers and developers to create a new breed of application, that fills the gap between traditional desktop, client-server and web based applications. Users will get the availability of an off-line laptop application, together with up to date data and materials, and the interactivity associated with a web application.

ColdFusion, Axis, Windows .NET and Web Services

Tuesday, March 25th, 2008

We have done a number of projects integrating with clients’ systems which have required either publishing or consuming web services. In the past we did this using Apache Axis. Since CF7 we have switched to ColdFusion which provides a very convenient way of developing Web Services.

When using web services in general

  • Methods passing simple types are very straight forward; just follow the Adobe documentation.
    • ColdFusion does a good job of converting the types.
    • Use javacast() if CF gets it wrong
  • Methods that pass a single class, map to a ColdFusion structure.
  • Methods that pass a nested class, map to a nested ColdFusion structure.
    • See the following example on calling the LiveCycle Reader Extensions web service
    • You may need to use ‘javacast()’ for null values

Specifically for .Net

  • Interoperability with .Net is now generally quite good
  • If the web services is using Windows authentication or you need to use SSL:
    • You need to replace the Apache Axis authentication library with a different Apache library. See here.
    • Drop the Jakatra libraries into the cold fusion lib directory and modify the client-config.wsdd
    • See also Tom Jordahl’s musings on this topic.
    • We tried in the CF8 beta program to get the Apache libraries into the default installation for ColdFusion8; hopefully it will find its way into a future version.
  • Other Apache Axis and .net hints can be found here.

Scotch on the Rocks and CFUnited Europe

Friday, March 14th, 2008

There are some good conferences this year for Cold Fusion developers in Europe, with Scotch on the Rocks now running over 3 days in June, Max coming to Europe for a second time in Italy in December, and earlier this week CFUnited on my doorstep in London.

At CFUnited there was a good turnout of ColdFusion developers. Ben Forta started off the conference in great style. I was good to see someone from the Indian CF team; Rakshith gave a good introduction to Ajax. Shlomy Ganz gave an engaging talk on project management. There were some interesting presentations by local enthusiasts like Mark Drew. And Nick Watson wrapped it up with his presentation on LCDS and BlazeDS

There was, however, a large reliance on a small set of speakers who did up to 3 talks each. Some were covering for speakers who were not able to attend. And there were too many of what I would call ’stocking filler’ and ‘RTFM’ talks.

I’m looking forward to Scotch where they appear to have a much larger, richer set of speakers. Hope to see you there.