Building and Executing a BizTalk Single Sign On Scenario

The Enterprise Single Sign On functionality that ships with BizTalk Server is fairly interesting, but can be tricky to set up. Below I walk through the steps I went through to get a fully-functional SSO demonstration running.

The very first thing to do is confirm that you have the necessary users and groups set up in your environment. As you see below, I've set up BizTalk SSO Administrators, BizTalk SSO Affiliate Administrators, and BizTalk SSO Application Users as groups, and defined a BTSSSOSvc user account that runs the SSO service. The user accounts for Richard and Bill are for employees who also belong to the BizTalk SSO Application Users group. Also, you want to make sure that the BizTalk Server Administrators group is added to the BizTalk SSO Affiliate Administrators group. Finally, ensure that the BTSSSOSvc service account belongs to both the BizTalk Application Users and BizTalk SSO Administrators group so that it can access the resources it needs. One last thing. SSO requires the participating BizTalk Hosts to be Trusted, and a host that is untrusted can't use the same service account as a trusted host, so, I've set up a BTSInProcTrustedSvc and BTSIsoTrustedSvc account. Got all that? If you do all this right the first time, you'll never have to worry about it again.

Next, you'll want to make sure you have the appropriate BizTalk Hosts and instances set up. I've created two new hosts (given that my default Application and Isolated hosts were non-trusted). Each of those hosts have instances created with the new "trusted" service accounts.

Now, I needed to build two "applications" which have to be accessed from my single BizTalk process. The easiest way to do this is to build web services, and then disable Windows Authentication and force a direct sign on. In our case, this simulates another application with entirely different credentials than those of the caller. My first web service application retrieves personal employee data (name, address, hire date) from a SQL Server table. The second application retrieves more private data (salary, vacation balance, 401(k) balance). Both of these are ASP.NET web services projects. As you can below, in IIS I turned on Basic Authentication which will prompt the caller for valid credentials.

Next we use the SSO management tools to create both the applications and user mappings for our two data retrieval apps. The command line tools are located in C:\Program Files\Common Files\Enterprise Single Sign On. If you run ssomanage -listapps you'll see any existing applications you've built. Building SSO applications (and user mappings) require feeding an XML file into the management tool. My configuration looks like:

<?xml version="1.0"?>
<SSO>
<application name="SSO_Demo_PrivateInfo">
<description>A demo SSO application that retrieves private employee info</description>
<contact>richard@test.com</contact>
<!-- Anyone in this group is a valid user -->
<appUserAccount>seroter\BizTalk SSO Application Users</appUserAccount>
<appAdminAccount>seroter\BizTalk SSO Affiliate Administrators</appAdminAccount>
<field ordinal="0" label="User ID" masked="no" />
<field ordinal="1" label="Password" masked="yes" />
<flags groupApp="no" configStoreApp="no" allowTickets="yes" validateTickets="yes" allowLocalAccounts="no" timeoutTickets="yes" adminAccountSame="no" enableApp="yes" />
</application>
</SSO>

Now I can run ssomanage -createapps "AffilateApp.xml" which would create each application(s) defined in the configuration.

Now I need to also create the user mappings for my SSO application. I again use a configuration file to do my dirty work:

<?xml version="1.0" ?>
<SSO>
<mapping>
<windowsDomain>seroter</windowsDomain>
<windowsUserId>Bill</windowsUserId>
<externalApplication>SSO_Demo_PrivateInfo</externalApplication>
<!-- These would normally be credentials to some other logon account -->
<externalUserId>seroter\bill</externalUserId>
</mapping>
<mapping>
<windowsDomain>seroter</windowsDomain>
<windowsUserId>Richard</windowsUserId>
<externalApplication>SSO_Demo_PrivateInfo</externalApplication>
<!-- These would normally be credentials to some other logon account -->
<externalUserId>seroter\richard</externalUserId>
</mapping>
</SSO>

As you might expect, now I run ssomanage -createmappings "AppUsers.xml" which creates the needed mappings. Now, just because you create the mappings, doesn't mean you are done setting up user accounts. Naturally, you still need to designate the passwords to the accounts. If you forget this, you'll have problems later. Set this up by executing ssomanage -setcredentials "seroter\Richard" "SSO_Demo_PrivateInfo" which then prompts you for the password for this affiliate application user. Again, usually this is some other system's login, but I'm simply using my identical AD credentials. I'm lazy like that. Run this command for each user and application to make sure everybody is set up.

Finally, we are ready to build our BizTalk application. Add two web references to the project, one for each of the applications built above. I built a single schema which we take it to the orchestration that kicks off the process. It contains all the elements that will be populated by the two applications, and then returned to the caller. My orchestration looks like this:

As you can see, I'm going to be wrapping this whole thing in a web service call, so that whoever kicks off this process, gets all this information back synchronously. A very very very important step is shown below in the Construct Message shape. You need to make sure the context properties get copied over from the input message to the message being sent to the affiliate application. There are key context properties (SSOTicket and OriginatorSID) that will be required by the port using SSO. In my process here, I have to build out input message to each application, copy context, and then aggregate the responses into a single response that I return from BizTalk.

Next we build and deploy the orchestration. Next I used the Web Service Publishing Wizard to generate a web service (and a port) for my orchestration. I then use the BizTalk Explorer to open the newly-created receive location. Check the Use Single Sign On checkbox. This will cause the port to request an SSO ticket and populates context properties on the inbound message.

For my send ports, I make sure that the two ports that I have for my web service applications are also set to use Single Sign On. Open the transport properties of the send port and set the credentials required by the service (in our case, Basic). Then choose to Use Single Sign On and pick which affiliate application to acquire the credentials from. Make sense?

Now bind the orchestration (confirming that it is going to be deployed in the Trusted host) and start it. FYI, I also made sure before starting the orchestration that the adapter was configured to run as a trusted host as well. Everyone in the SSO process has to be Trusted to ensure that a valid SID is passed around.

Finally, I created a single ASP.NET application that mimics a simple portal. It calls my (BizTalk) web service, gets the response, and loads it into various web parts. We haven't gotten in the whole "how does Sharepoint Single Sign On work with this" discussion, as I'll leave that for a later post. Nonetheless, the ASP.NET application looks like this:

If I log out of my farm machine and log back in as "Richard", then I naturally get different results since I am now acting as a different user. So there you go, all the fun of SSO in a single post. Note that SSO is a very powerful system that also exposes an API for use by other .NET application besides BizTalk. Also be aware that BizTalk Server 2006 has made some great SSO enhancements around SSO management by providing a graphical UI to use as an alternate to the command line/configuration bonanza.