Tuesday 4 March 2008

Using the SSO database for storing configuration data

Single Sign-on is something that is often overlooked as being related only to Parties and for management of credentials. However, in its raw form, SSO provides a secure data store that can be used to store any information your application needs. In fact it can be used by non-BizTalk applications and doesn't have to only be for sensitive data, though this is the most typical usage.

In order to use SSO programmatically, an API is provided for accessing data. An MMC snap-in is also supplied for administrative purposes and third-party tools also exist for this purpose. Command line based tools also exist enabling scripting support.

Adding new configuration items to SSO

Using the tools supplied out-of-the-box with BizTalk 2006 R2, it is pretty easy to create an SSO schema and populate it with some data.

Create a schema for the configuration data. This is an XML file that look like the following:

<sso>
    <application name="Application Name here">
        <description>Description here</description>
        <contact>email address here</contact>
        <appuserAccount>domain\AppUserAccount</appuserAccount>
        <appAdminAccount>domain\AppAdminAccount</appAdminAccount>
        <field ordinal="0" label="reserved" masked="no" />
        <field ordinal="1" label="field name here" masked="no" />
        <field ordinal="2" label="field name here" masked="yes" />
        <flags groupApp="no" configStoreApp="no" allowTickets="no"
           validateTickets="yes" allowLocalAccounts="no" timeoutTickets="yes"
           adminAccountSame="no" enableApp="no" />
    </application>
</sso>

You can create as many fields as needed and multiple applications too. Note that the first field should not be used for a custom setting and is reserved for internal use.

Use the ssomanage.exe command line tool (in the C:\Program Files\Common Files\Enterprise Single Sign-On\ folder) to create the SSO application based upon the schema. To do so use the -createapps option specifying the filename of the schema XML created above. The application has access control for user and administrators based upon groups. By default these are the “BizTalk Application Users” and “BizTalk Server Administrators” groups respectively.

ssomanage -createapps "MySchema.xml"

To populate the schema with some data, use the BTSScnSSOApplicationConfig.exe command line tool (supplied with source code) in the C:\Program Files\Microsoft BizTalk Server 2006\SDK\Common\SsoApplicationConfig folder. Run Setup.bat to compile the tool and the executable should be generated in the bin folder.

BTSScnSSOApplicationConfig.exe -set AppName "ConfigProperties" "paramname" "paramvalue"

To retrieve a data item

BTSScnSSOApplicationConfig.exe -get AppName "ConfigProperties" "paramname"

Retrieving SSO configuration values in code

Once the data is stored, it can be accessed using the API. BizTalk 2006 comes with a client DLL which can be used to create a configuration reader class. In most instances it is recommended to create a type safe version to convert data items from their name/value pairs into the correct data type.

  • Add a reference to assembly Microsoft.BizTalk.InterOp.SSOClient.dll
  • Create a Property Bag that implements from IPropertyBag

public class ConfigurationPropertyBag : IPropertyBag
{
    private HybridDictionary properties;

    internal ConfigurationPropertyBag()
    {
        properties = new HybridDictionary();
    }

    public void Read(string propName, out object ptrVar, int errLog)
    {
        ptrVar = properties[propName];
    }

    public void Write(string propName, ref object ptrVar)
    {
        properties.Add(propName, ptrVar);
    }

    public bool Contains(string key)
    {
        return properties.Contains(key);
    }

    public void Remove(string key)
    {
        properties.Remove(key);
    }

}

  • Use the SSOConfigStore class to access the data using the property bag

public static class SSOConfigHelper
{

    private static string idenifierGUID = "ConfigProperties";

    /// <summary>
    /// Read method helps get configuration data
    /// </summary>
    /// <param name="appName">The name of the affiliate application
    /// to represent the configuration container to access</param>
    /// <param name="propName">The property name to read</param>
    /// <returns>
    ///  The value of the property stored in the given affiliate
    /// application of this component.
    /// </returns>
    public static string Read(string appName, string propName)
    {
        try
        {
            SSOConfigStore ssoStore = new SSOConfigStore();
            ConfigurationPropertyBag appMgmtBag = new ConfigurationPropertyBag();
            ((ISSOConfigStore) ssoStore).GetConfigInfo(appName, idenifierGUID, SSOFlag.SSO_FLAG_RUNTIME, (IPropertyBag) appMgmtBag);
            object propertyValue = null;
            appMgmtBag.Read(propName, out propertyValue, 0);
            return (string)propertyValue;
        }
        catch (Exception e)
        {
            System.Diagnostics.Trace.WriteLine(e.Message);
            throw;
        }
    }
}

Whilst the use of these command line tools is potentially advantageous from a scripting perspective, their use on an ad-hoc basis is not ideal. An MMC snap-in now exists for managing an SSO database. Richard Seroter has written a really cool configuration tool for managing configuration data which has a handy export feature that will export the application schema as an XML file. Source code is also available.