Koen about .Net

September 5, 2011

Experiences building a Task based Silverlight application

Filed under: Development — Tags: , , — koenwillemse @ 21:30

I’ve been very interested in stuff like CQRS and Task Based user interfaces lately, but unfortunately I can’t work with it on the current assignment. So I decided to create a private project in which I can try out all the related technology, techniques and best practices I can find. So this is the list of tools and techniques I’m going to use:

Techniques / methodologies

  • CQRS
    I do like the idea of Command Query Responsibility Segregation which I first read about in posts by Greg Young on codebetter. If you want more info about that, read the posts by Greg Young or Udi Dahan also has some interesting blog posts about it. Other great sources of information are cqrsinfo.com and the DDD/CQRS google group.
  • Task based UI
    The idea behind a task based user interface is of course the focus on the user and making the user interface in such a way that it makes working with it easy from the perspective of an user. It also works great together with CQRS and is almost a prerequisite to doing DDD al the way.
  • DDD
    Domain Driven Design is a fundamental part when designing an LOB application I think. A great source of information is Applying-Domain-Driven Design and Patterns by Jimmy Nilsson.
  • TDD
    Test driven development… What more is there to say about that. If you don’t know what it means. Go read about it!!!
  • ATDD
    This one is not that well known as TDD, but it stands for Acceptance Test Driven Development. Unfortunately I haven’t had the change to work on a project at a customer where it’s used, but I’ve been trying it out in an MVC project I’ve been doing and I’m convinced that it definitely helps creating better software and preventing regression problems.

Tools

  • NuGet
    NuGet just makes your life a lot easier regarding installing packages en it’s dependencies.
  • Caliburn.Micro
    I’ve been experimenting with Prism in the past and it was pretty big to get started with. A colleague of mine talked about Caliburn.Micro several times and I wanted to give it a spin to see if it is easier.
  • AutoFac
    I need an IoC container in the Silverlight client and I now of two that I’ve heard of and that is Unity and Autofac. Some recent blog posts I’ve read about their performance made me decide to ditch Unity and give AutoFac a spin.
  • StructureMap
    I’ve worked with StructureMap in the previous project and I really liked it. Next to that it looks pretty good in performance comparisons so I wanted to use it as the IoC container in my web application project hosting the services.
  • Silverlight
    In my opinion Silverlight is a very logical choice when implementing a LOB application which should be available using the web. Especially when there is no need to target a very wide range of users, with all kind of operating systems and browsers. Otherwise I would probably have chosen for ASP.NET MVC with jQuery, but Silverlight is the best match for the application I’ll be building.
  • WCF
    I will be using web services build using WCF for the communication of the Silverlight client with the web server to get the data from the SQL Server Express database. I will be looking at both plain WCF services and WCF data services.
  • SpecFlow
    I’ve been trying out Specflow as the way to write my ATDD tests using Gherkin syntax. It integrates nicely with Visual Studio so I will be using that again.

When looking at the architecture of the application, it will have a lot of similarities with the Silverlight Cookbook application on codeplex which my colleague Dennis Doomen created.

I will update this post with links to other blog posts when I have some experiences worth sharing with any of these points.

Follow up posts:

  1. Testing and deployment

June 28, 2011

Thread safe DateTime for unit testing

Filed under: Development, dotnetmag, Testing — Tags: — koenwillemse @ 16:00

We’ve been using the construction of a wrapper class around the DateTime for unit testing which Ayende described here.

Today one of my colleagues discovered that there is a possibility to run multiple unittests in parallel. How to do that is described here. However, the approach we used with the SystemDateTime class no longer worked, since it uses a static field which caused problem with two tests running at the same time. I tweaked it a bit to fix this, so I wanted to share the code we use for it.

/// <summary>
/// Facade for the System.DateTime class that makes it possible to mock the current time.
/// </summary>
public static class SystemDateTime
{
    [ThreadStatic]
    private static Func<DateTime> now;

    [ThreadStatic]
    private static Func<DateTime> today;

    /// <summary>
    /// Returns the current time as a DateTime object.
    /// </summary>
    public static Func<DateTime> Now
    {
        get { return now ?? (now = () => DateTime.Now.Truncate()); }
        set { now = value; }
    }

    /// <summary>
    /// Gets the current date.
    /// </summary>
    public static Func<DateTime> Today
    {
        get { return today ?? (today = () => Now().Date); }
        set { today = value; }
    }
}

Hope it helps some of you.

May 5, 2011

Converting User Controls into Custom Controls

Filed under: Development — Tags: , — koenwillemse @ 16:30

In the project I’ve been working on, we had to deal with a design agency, which creates a lot of html markup, which must stay exactly the way it was created by them be. Next to that, the product should eventually work in SharePoint, so we have to use WebForms :-(. I’ve been developing a framework which will be used which looks very similar to the FrontController pattern, however there are a few differences, for instance, the Commands (or ViewActions as we call them) will not give a ActionResult, but our controller will do this, since there is a lot of knowledge there around navigation between forms etcetera. But that’s not the subject of this post.

One of the things we’ve also been working on is to make the transition of the designers stuff to the asp.net stuff as small as possible, so that changes made by them can easily be merged in our controls. So the designers have been working on control-like pieces of html which will be reused to compose pages. Nothing strange here from a developers point of view, so we made UserControls out of them which will be the equivalent of their control-like html markup. These UserControls had to be used in several portal web project. So there were a few options on the reuse of the controls:

  1. Create CustomControls for each control-like element of the designersThis was not an option because the html delivered by the designers was sometimes very much in one control (over 300 lines) which would make it a nightmare (and laborious task) to keep CustomControl in sync with their markup files.
  2. Use the ‘Add as Link’ option to add the user controls to the portal projectsThis option was killed by the specific software factory what we had to use, since that didn’t support this construction which made all several nightly builds fail.
  3. Copy each UserControl to each portal projectYeah right… not an option at all of course.
  4. Convert UserControls into CustomControls.OK, that option was the only option left worth investigating.

So I had some work to do. This post by David Ebbo was a very good starting point on how to do it. So I started out with a small demo project where I did all the steps outlined by David and I got that part working. However, there were some things that were not the way we wanted it.

  1. The fixednames was not handy for us since we want to have one resulting dll, otherwise there were way to many dlls to reference in the portal projects.
  2. The name of the assembly of the controls was something like App_Web_BLABLA_ascx.dll which just looks ugly and might change over time, which made it useless for us in a automated scenario.
  3. The functionality should be integrated in the build of the project, to be able to make it work how the other projects work using the software factory

So I started out to fix these points. The first two points I wanted to fix was to merge the assemblies that were created and name them the way I wanted it. So I started with using ILMerge to do this. In my demo I had created two very small user controls to do this and after the ILMerge, it seemed to work. I then added a larger user control and tried that also, but that one just did not work correctly. Just a small part of the markup was visible and that was it. I did a lot of googling on it but eventually found out that when you go over a specific number of characters in your user control (I can’t remember the actual amount anymore :-(), resources are used in the generated code. And then ILMerge breaks it. After being stuck there for a while, one of my colleagues mentioned that I could try aspnet_merge instead. I didn’t know that it existed, but I tried it out and it worked like a charm.

So I only had to fix the 3rd point mentioned above. The software factory has a mechanism built in to copy assemblies created by the project to a specific location every time you build the project. So that lead me to the idea to add the aspnet_compile and aspnet_merge as a post build command, since the magic of the software factory was done using a AfterBuild MSBuild task, so I could not use that. Eventually my post-build command looked like this:

rmdir /S /Q "%TEMP%\Publish_$(TargetName)"
del  "%CD%\$(TargetName).dll"
del  "%CD%\$(TargetName).pdb"

"C:\Windows\Microsoft.NET\Framework\v2.0.50727\aspnet_compiler.exe" -v "$(ProjectName)" -p "%CD%\.." -f "%TEMP%\Publish_$(TargetName)"

"C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\aspnet_merge.exe" "%TEMP%\Publish_$(TargetName)" -keyfile "%CD%\..\..\..\..\src\_Key\Product.snk" -a -copyattrs -o $(TargetName) -debug

copy "%TEMP%\Publish_$(TargetName)\bin\$(TargetName).dll" "%CD%\$(TargetName).dll" /Y
copy "%TEMP%\Publish_$(TargetName)\bin\$(TargetName).pdb" "%CD%\$(TargetName).pdb" /Y

 

First I remove the directory where I’m going to publish the web app (using the aspnet_compile).
Next step is also related to the software factory workings. The resulting assembly of the project has to be exactly the same name, otherwise it won’t be copied. So I delete the current dll created by the project, otherwise my aspnet_merge step will create an assembly which is not exactly the name I wanted. However, the result is that there can’t be worked with code behind files, but that was not a problem for this.
Then I use aspnet_compile to precompile the site and write the resulting stuff to a temporary folder.
Then the aspnet_merge is  executed to merge the created App_Web assemblies to one assembly with the same name as the assembly that would have been created by my original web application project. Note that I’m also resigning the assembly to make sure it is strong named.
The last step is to copy the merged dll and pdb files back to the original location.

With this small piece of post-build commands I got the solution eventually working and it is being used now in multiple solutions without problems. I hope some of you guys can also benefit from this. Please let me know if it helps.

February 16, 2011

Custom C# formatter for Selenium

Filed under: Development, dotnetmag, Testing — Tags: , , — koenwillemse @ 22:20

In my previous post I mentioned that I had been working on a C# formatter for selenium which uses MSTest as test framework and also FluentAssertions to make the tests more readable. After a few hours last Saturday night I had something working which looks pretty ok for now. I guess I’m not the only one wanting to generate this code, so I wanted to share what I’ve got.

I started off by taking the source of the C# formatter which is installed together with the selenium IDE. Note that there is a bug (maybe more, but I ran into this one Winking smile) in the source, which results in a lack of options to set in the IDE. The problem is regarding the configForm setting, which is done in the options. This is pretty strange if you look at it, because that configForm is used to generate the UI for the options (which options are available can be found here). The configForm should be set outside the options. I tried to modify the source, but that’s not possible, it’s read-only. If you still want to use the NUnit formatting as done in the formatter, you can add another formatter and add the modified source. You can download the modified source here.

Now to the formatter I wrote. I wanted a few things:

  • MSTest as test framework
  • use FluentAssertions for readability
  • Start the selenium server when starting test run (and close it when tests finished)

There is a description here on how to start creating a custom formatter. However, I was lazy, so I copied the source from the existing C# formatter and modified it to accommodate my needs. First of all I fixed the problem with the options, which I described above.
Next I changed the assertion methods to use the FluentAssertions syntax.
I updated the generated header and footer, since I don’t want all the initialization of a Selenium instance etc. to be done on every TestInitialize since it takes several seconds. I changed it to be done on a central location.

The biggest change I made was add formatting for a test suite, which is not available in the default C# formatter. In the code for the test suite, I added methods for AssemblyInitialize and AssemblyCleanup. In these method, I will start and tear down the selenium server process and the selenium instance. This uses a static selenium instance, so this will cause problems if you want to use it in a multi-threaded environment, but for now, it matches my needs. The complete source of the formatter can be downloaded here.

I hope some of you find this helpful also. If you have some good suggestions for the formatter, then please let me know.

Edit 22-02-2011: The links to the sources were incorrect. I updated the links now, so you can download the files from my skydrive.

February 15, 2011

Comparison of Web UI Testing toolkits

Filed under: Development, dotnetmag, Testing — Tags: , , — koenwillemse @ 16:00

I wanted to started using web UI tests because the current project I’m working on I lacking this and for my personal web shop application I also need it. So I had to make a choice for a testing framework. I already knew of Coded UI Tests in Visual Studio 2010 and Selenium. Another colleague at my current project also mentioned Watin, so I decided to do a quick test of the three and see if it matches my expectations.

Coded UI Tests in Visual Studio

This was my first choice, since it’s integrated in Visual Studio which makes it easier when testing my deployed applications from a build server. So I started by creating the test in de Visual Studio IDE and I clicked some pages. Then added a few assertions and done. Generated the coded test and I looked at the coded that was generated. And that what a bit of a shock Sad smile. It was very unreadable code, which actually shouldn’t matter since it’s generated code, but when you would like to tweak or edit it a bit (like I want) it’s not very nice to do that. I wanted to edit the tests to be able to use some parameters and stuff to make the tests more robust.
Now there is also the option of created tests using the Test Manager in Visual Studio 2010, but I haven’t tried this. That’s something I still want to do, to see if this makes it easier or better. For now, I’m a bit disappointed in using the coded UI tests. When I’ve got some time left, I’m going to check how the creation of coded UI tests is when using the Visual Studio 2010 Test Manager

Selenium

Selenium is a tool which I’ve heard of several times, so I wanted to give it a try now myself. First you’ll have to install some stuff. I installed the following:

After installing all stuff (which is more work than I wanted Winking smile) I started creating my first test. Clicking the test and verifications is also pretty easy with the integration in Firefox. Then creating the code. There are a few formatters available, one of them being for c#, so I generated the code, but unfortunately it was based on NUnit and there was some stuff in it I didn’t like. But before I gave up, I looked a bit better in Selenium IDE and I saw that there is also the possibility to create your own formatter, so I decided to give that a try. It took some time with some mistakes that I made, but eventually I had a working formatter which created the C# code the way I wanted it. So I started the tests in visual studio (after starting the java application for the selenium server) and it worked Smile.

Watin

Because my colleague mentioned this framework, I wanted to give it a try. Unfortunately there was no IDE or something to create the tests. Since I was already more convinced of both other frameworks, I didn’t want to spend more time on this one, since it was also more difficult to work with it in code only mode.

Comparison

So a small comparison

  Coded UI Tests Selenium Watin
Positive
  • Integrated in Visual Studio, so no installation required
  • Control over the generated code
  • Code easy to modify / extend
 
Negative
  • Ugly generated code
  • IDE is a bit buggy
  • Custom installation required
  • No IDE
  • Difficult to work with

So eventually I chose selenium for now, since some other people on my current project are also trying it out and were positive about it. I’ll write another blog post on the custom formatter I’ve been working on. It generates code for the MSTest framework and makes use of the FluentAssertions to make the tests more readable.

February 8, 2011

Crystal reports runtime for .NET 4.0

Filed under: Development, dotnetmag — Tags: , — koenwillemse @ 00:00

A few years ago I created an application which is used by an tutoring institute. It’s not the best application I’ve ever created (and that’s a bit of an understatement), but it works. There are some bugs now and then, some new feature request, which I do when I’ve got some spare time. One part of the application is generating invoices. I used Crystal reports to generate the invoices (first version in VS 2005, later in VS 2008).

A while ago I upgraded my solution to Visual Studio 2010 and then the problems began. Crystal Reports is no longer included in Visual Studio but needs to be downloaded separately from SAP site. Problem one, it took a long time before the final version for .NET 4.0 and Visual Studio 2010 was available. I started using the beta version when I upgraded and it worked OK. The problem however was that there was decent no runtime installation available. I found a blog post (unfortunately I don’t have the link anymore) which indicated that you could redirect the newer assemblies to the ‘old’ VS 2008 version runtime. This worked out good for me so I was ok.

In November last year, the production release of Crystal Reports for Visual Studio 2010 was ready. So when I got my new work laptop in December, I installed this last version. But then, last week I fixed a few minor bugs and made a little improvement, and I got in trouble with the deployment which complained about the Crystal Reports references. So I wanted to quickly download the runtime for the newer Crystal Reports version and install it on the client computer. However, that wasn’t done quickly. It took me a while to finally find the links to the redistributables and merge modules of the new runtime. One thing became clear and that was that I really dislike the SAP web site.

I finally found the links, so I wanted to post them here, so maybe some other people don’t have to spend the same amount of time as I had to, to find the installers (with thanks to Coy Yonce):

  • Standard EXE installation package which installs SAP Crystal Reports for Visual Studio into the Visual Studio 2010 IDE can be found here.
  • Click-Once installation package used to create self-updating Windows-based applications which can be installed and run with minimal user interaction can be found here.
  • Merge Modules installation package used to install components which are shared by multiple applications can be found here.
  • Redistributable installation (32 bit) can be found here.
  • Redistributable installation (64 bit) can be found here.

I hope this saves some time for you.

January 22, 2011

Culture specific website in ASP.NET MVC

Filed under: Development — Tags: , — koenwillemse @ 00:36

In my personal time I’m working on a web shop application. It’s an application which is really going to be used, so not like the usual throw-away home projects. I could off course just grab an already existing application, but I’m too geeky for that Winking smile. I also wanted to use it to learn a lot about working with ASP.NET MVC and jQuery.

One of the requirements is that it have to support multiple languages. I wanted to do this the way you see it at for instance http://msdn.microsoft.com/nl-nl/ with the culture code in the url. So far so good. I started out by using a feature in ASP.NET MVC which I found, and that was by using a FilterAttribute in combination with an ActionFilter which I found here: http://helios.ca/2009/05/27/aspnet-mvc-and-localization/. Nice solution I thought, so I took that code, modified it a bit to match my scenario and it worked.

But then when I added more views to the application, I started to notice that it was not a good solution at all, because of the following reasons:

  1. I had to change my routes so they would work correctly with the culture code in the url (urls will look like this: http://www.pastechi.nl/nl-NL/Products/Index etc). Maybe this wasn’t necessary and it is because I’m not completely familiar with the routing in ASP.NET, but still, it was not what i wanted.
  2. Every action on my controller now had a parameter cultureCode, which was not used in that method, because the culture code was set in the FilterAttribute code.
  3. It just felt wrong Winking smile

So I started thinking about it and I came to the conclusion that I just brought a knife to a gun fight. The solution works, but is not very usefull. So what would be better? Well, the new solution I’ve got implemented uses url rewriting. The url rewriting is done using the Application_BeginRequest event and takes place before the routing engine of ASP.NET MVC is doing it’s magic. So I created a simple HttpModule which can be used to rewrite the url, by removing the culture code from the url and placing the culture code in a suitable location.

This is the code I wrote (keep in my that this is the POC code, so it should be rewritten a bit to be unit testable etc).

using System;
using System.Text.RegularExpressions;
using System.Web;

namespace HttpModules
{
    public class CulturePathRewriteModule : IHttpModule
    {
        public void Init(HttpApplication context)
        {
            context.BeginRequest += OnBeginRequest;
        }

        static void OnBeginRequest(object sender, EventArgs e)
        {
            var request = HttpContext.Current.Request;
            var cultureRegEx = new Regex(@"(^\/[A-z]{2}\-[A-z]{2})|(^\/[A-z]{2}\-[A-z]{2}.*)");

            if (cultureRegEx.IsMatch(request.Url.AbsolutePath))
            {
                string cultureCode = request.Url.AbsolutePath.Remove(0, 1).Substring(0, 5);
                string newAbsolutePath = request.Url.AbsolutePath.Remove(0, 6);
                string newUrl = "~" + newAbsolutePath;

                HttpContext.Current.Items["currentCultureCode"] = cultureCode.ToLower();
                HttpContext.Current.RewritePath(newUrl);
            }
        }

        public void Dispose()
        {
        }
     }
}

You probably noticed that I didn’t set the CurrentCulture / CurrentUICulture on the current thread. It’s not that I don’t know that it exists, but I can’t use it. One of the languages that I want to support doesn’t have an official CultureCode. Off course, you can create this if you want, but because the site will be running on a shared hosting partner, that is not an option. The eventual code won’t place it in the context using a hardcoded key, but it will be done using a custom wrapper on the context which I can use typed, but you’ve got the idea.

January 7, 2011

Unit Test Adapter threw exception: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information. – Part 2

Filed under: Development — Tags: , — koenwillemse @ 09:46

In a previous post I wrote about a problem I had with running unittests, which resulted in an exception with the message ‘Unit Test Adapter threw exception: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.’.

This morning, on my new project, I ran into the same problem after I deleted my TFS workspace locally and got everything new from the server in a different location (a new workspace). So I looked back at my previous post, tried what I wrote there, and….. still the exception :-(. To see if it would lead to more information, I started the tests in debug mode. And… all tests passed as usually. Strange…
I found the problem eventually. The assembly being tested was strongly named. Because we use the code coverage from the unittests, we had to re-sign the assembly tested after instrumentation and we set this up in the Code Coverage section in the testrunconfig.testrunconfig. Now what was the problem? The path to this key file was wrong! I made the mistake that the location pointed out there was a absolute location, instead of a relative location compared to my testrunconfig. So I changed this, cleaned my solution, rebuild the solution and ran the tests. And all tests passed again.

Another lesson learned. Whatch out that you don’t accidentally have absolute paths when referencing stuff which is located in your source control tree.

September 2, 2010

Configuration of WIF

Filed under: Development, dotnetmag — Tags: , — koenwillemse @ 16:15

The current project I’m working on is a Identity Management Solution for a client. We’re working with WIF (as you might have noticed in my previous posts) and SPML v2. I’ve been beating my head against a wall for the last few days because we had all kind of problems to get the Identity Delegation scenario working. Eventually it was a small thing which caused all kinds of problems, but I’ll elaborate on that in a different post.

One thing that I found frustrating is the lack of documentation for WIF and especially that it’s difficult that way to configure the identity related stuff correctly. We figured out now what all the configuration items in the microsoft.IdentityModel section mean, so I’m sharing it here so that other people starting with WIF don’t have the same giant learning curve we had ;-).

For a consuming application, the following is a common configuration when using an active STS (note that we use the .NET 3.5 targeted assemblies):

<microsoft.identityModel>
    <service saveBootstrapTokens="true">
        <issuerNameRegistry type="Microsoft.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
            <trustedIssuers>
                <add thumbprint="9dbc8c485022a10788832ab285a6281fe18a22de" name="CN=sts" />
            </trustedIssuers>
        </issuerNameRegistry>
        <audienceUris>
            <add value="http://frontend" />
        </audienceUris>
        <securityTokenHandlers></securityTokenHandlers>
        <federatedAuthentication>
            <wsFederation passiveRedirectEnabled="false" issuer="https://sts/SecurityTokenService.svc" realm="http://frontend" requireHttps="false" />
            <cookieHandler requireSsl="false" />
        </federatedAuthentication>
        <serviceCertificate>
            <certificateReference x509FindType="FindByThumbprint" findValue="4fa9361d1ddda6e8847313a56ab96412dd40f13b" storeLocation="LocalMachine" storeName="My"/>
        </serviceCertificate>
     </service>
</microsoft.identityModel>

Now what does all this mean and what is it for?

  1. saveBootstrapTokens=”true”
    This means that when WIF makes an ClaimsIdentity from a received SecurityToken, that the property BootstrapToken of the ClaimsIdentity will be the actual token received. I wish I had found about this earlier.
  2. issuerNameRegistry
    This section indicates which sts you trust. Here you add the certificate(s) which are used to sign the tokens you receive from the STS
  3. audienceUris
    This section is used to check whether the received information from the STS is applicable to you as the calling application. It should match the AppliesTo property which you set when you issue a RequestForSecurityToken to your STS.
  4. securityTokenHandlers
    In this section you can remove the default handlers and add your own token handlers. Note 1: Don’t clear the collection, because most of them are necessary. If you want to use a custom, then only remove the default of the type you want to add. Note 2: Be very careful with what you do here. One wrong decision here has cost us a lot of hours of bug hunting.
  5. federatedAuthentication
    This section contains information to determine if you are using an active or passive scenario. When you have a passive scenario (when the browser handles the redirects etcetera for you) then you set passiveRedirectEnabled=”true”. You have to make sure then that the correct issuer and realm and other related attributes are set.
    The cookieHandler requireSsl attribute indicates whether the written session cookie requires SSL. When you are working on a non-ssl connection and you forget to set this to false, your cookies won’t be preserved over postbacks.
  6. serviceCertificate
    This section was the least clear to me when starting out. It is for defining which certificate should be used to decrypt the incoming SecurityToken.

When you setup these values correctly, you should get up and running pretty quickly. This post is just for making clear what each section of the configuration is for. To get an overview of all steps to do for getting up and running using an active STS, please read my previous post about making a web application use an active STS.

I hope this helps some of you to save some time when configuring WIF.

August 2, 2010

Making a web application use an active STS

Filed under: Development, dotnetmag — Tags: , , , — koenwillemse @ 19:46

At my current assignment we’re working on a solution which among others consists of a custom Security Token Service which is used for the authentication of users in a web portal. In our case we’ve created an active STS by using Windows Identity Foundation and WCF. We’re now working a demo web application which uses the STS (and some other functionality we’re building) to show the team which creates the portal how they should consume the STS.

Since there is almost NO decent documentation about WIF, I started googling. The problem which I ran into was that the information I found was almost all about scenario’s with a passive STS. I found a bit information about consuming an active STS but all not complete, so I’ll put all the steps I had to take right here, so it can help some others.

First of all, I eventually found this blog post, which made it almost work for me. There was just some information missing which caused me to search for another 1 – 2 hours.

These are the steps to take when you want to consume an active STS from a web application:

  1. Add a reference to the Microsoft.IdentityModel assembly (WIF).
  2. Add the definition of the microsoft.IdentityModel config section to your config like this (check the correct version of the dll of course):
    <section name="microsoft.identityModel" type="Microsoft.IdentityModel.Configuration.MicrosoftIdentityModelSection, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
    
  3. Add the following two HttpModules to your config (when using IIS7, add them to you system.webserver section, otherwise to you system.web section):
    <add name="WSFederationAuthenticationModule" type="Microsoft.IdentityModel.Web.WSFederationAuthenticationModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
    add name="SessionAuthenticationModule" type="Microsoft.IdentityModel.Web.SessionAuthenticationModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
  4. The authentication mode should be set to None:
    <authentication mode="None" />
  5. Add the configuration for the microsoft.IdentityModel section, for instance:
    <microsoft.identityModel>
    <service>
    <issuerNameRegistry type="Microsoft.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
    <trustedIssuers>
    <add thumbprint="{Add the thumbprint of the certificate used by your STS, for instance: 80481e4041bd6758400c62e2c811831b98eed561}" name="{Add the name of the certificate, for instance: CN=devsts}" />
    </trustedIssuers>
    </issuerNameRegistry>
    <audienceUris>
    <add value="{Add the applies to url of your web application}"/>
    </audienceUris>
    <federatedAuthentication>
    <wsFederation passiveRedirectEnabled="false" issuer="{The address of the STS, for instance: https://devsts/mySts.svc}" realm="{The applies to address of your web application, for instance: http://myrelyingparty.nl}" persistentCookiesOnPassiveRedirects="true" />
    <cookieHandler requireSsl="false" />
    </federatedAuthentication>
    <serviceCertificate>
    <certificateReference x509FindType="FindByThumbprint" findValue="{The certificate used by your STS, for instance: 80481e4041bd6758400c62e2c811831b98eed561}" storeLocation="LocalMachine" storeName="My"/>
    </serviceCertificate>
    </service>
    </microsoft.identityModel> 

    As you can see, you register your information about the certificate being used by your sts and the information about your application, the relying party.
    The line about the cookieHandler was the one that caused me some problems because I didn’t have that. The problem is that my local site was working on http and not https, but the created cookies required https. I didn’t have this line at first, which had the effect that the session cookie was not maintained over postbacks.

  6. After you’ve configured everything, you can use the following code to consume your STS and get an IClaimsIdentity:
    // authenticate with WS-Trust endpoint
    var factory = new WSTrustChannelFactory(
    new UserNameWSTrustBinding(SecurityMode.TransportWithMessageCredential),
    new EndpointAddress("<a href="https://devsts/MySts.svc">https://devsts/MySts.svc</a>"));
    factory.Credentials.UserName.UserName = usernameField.Text;
    factory.Credentials.UserName.Password = passwordField.Text;
    var channel = factory.CreateChannel();
    var rst = new RequestSecurityToken
    {
    RequestType = RequestTypes.Issue,
    AppliesTo = new EndpointAddress("http://myrelyingparty.nl/"),
    KeyType = KeyTypes.Bearer
    };
    var genericToken = channel.Issue(rst) as GenericXmlSecurityToken;
    // Now you parse and validate the token which results in a claimsidentity
    var handlers = FederatedAuthentication.ServiceConfiguration.SecurityTokenHandlers;
    var token = handlers.ReadToken(new XmlTextReader(new StringReader(genericToken.TokenXml.OuterXml)));
    var identity = handlers.ValidateToken(token).First();
    
    // Create the session token using WIF and write the session token to a cookie
    var sessionToken = new SessionSecurityToken(ClaimsPrincipal.CreateFromIdentity(identity));
    FederatedAuthentication.SessionAuthenticationModule.WriteSessionTokenToCookie(sessionToken);
    
    //Perform some redirect
    Response.Redirect("~/secure/default.aspx");
    

In our situation, this was not complete, since we need the SAML token received from the STS furtheron to authenticate to WCF services which we consume. After using reflector and trying something out, it can be easily done by changing just two lines of code. I can be done by the following:

var identity = handlers.ValidateToken(token).First();
Thread.CurrentPrincipal = new ClaimsPrincipal(new IClaimsIdentity [] { new ClaimsIdentity(identity.Claims, token) });

The code itself looks probably a bit strange, since we get a ClaimsIdentity from the ValidateToken and then we create another ClaimsIdentity. I hoped that WIF would have used this way to construct the identity, of at least provide an overload or something to do this. I created the identity like this, since the securitytoken is now availalbe in the BootstrapToken property of the ClaimsIdentity. At first we were thinking that we had to keep the security token in session but that is not necessary when you do it like this. Now we can access it simply with the following lines of code:

var identity = Thread.CurrentPrincipal.Identity as ClaimsIdentity;
var theOriginalSecurityToken = identity.BootstrapToken;

I hope this helps somebody else. It would have saved me a lot of time if I could have found this information somewhere.

Update (17-8-2010)

We’ve been using the code as listed above, but we ran into some problems, because the retrieved token is a GenericXmlSecurityToken which caused problems when supplying it to our backend services.

After some searching I found that it is possible to get the BootstrapToken property filled by WIF, but you need to set a configuration switch (some decent documentation would really be helpfull). All you have to do is change the following in your web application configuration (add the saveBootstrapTokens attribute):

<microsoft.identityModel>
<service saveBootstrapTokens="true>
<issuerNameRegistry ……

The code to creating your principal is then the following:

var identity = handlers.ValidateToken(token).First();
Thread.CurrentPrincipal = new ClaimsPrincipal(new [] { identity });

Now the BootstrapperToken is a SamlSecurityToken which is exactly what we want to be able to authenticate to the backend services. I’ll show in a new post how we have all this tied together.

Older Posts »

Blog at WordPress.com.

%d bloggers like this: