try-catch-FAIL

Failure is inevitable

NAVIGATION - SEARCH

Using SpecsFor.Mvc with Windows Authentication

Numerous people have requested that I put together a sample that illustrates how to use SpecsFor.Mvc with Windows Authentication.  Guess what’s in this post? Smile

Specifying your own ApplicationHost.config file for SpecsFor.Mvc to use is the secret to getting Windows Authentication to work.  I’m going to assume you’ve already got your web project configured to use Windows Authentication.  If not, that’s a can of worms for a different post (or perhaps Stack Overflow?)  This post will focus just on configuring the spec project.  First, let’s create our host file!

Add a new config file to your spec project called ApplicationHost.config.  Modify the properties for this file so that it’s copied to the output directory.

image

Now drop in the standard XML for an IIS Express application config file.  If you don’t know what that is (I sure didn’t!), you can use this file from the sample project.

There are two changes you’ll need to make.  First, find the <sites> element, and change the name of the only site in the file to match the name of the project you’re writing specs against.  SpecsFor will overwrite this site definition at runtime.

Next, jump to the end of the file, and add a location block (or change the path on the existing one if you’re using the config file from the sample), like so:

<location path="YOUR_PROJECT_NAME_HERE">
  <system.webServer>
    <security>
      <authentication>
        <windowsAuthentication enabled="true" />
        <anonymousAuthentication enabled="false" />
      </authentication>
    </security>
  </system.webServer>
</location>

Again, be sure you set the path attribute to match the name of the project you are writing specs against!

Now you’re ready to configure SpecsFor.Mvc!  Create a setup fixture in the root of your spec project, like so:

[SetUpFixture]
public class SpecConfig
{
    private SpecsForIntegrationHost _host;

    [SetUp]
    public void Setup()
    {
        var config = new SpecsForMvcConfig();
        config.UseIISExpress()
            .ApplicationHostConfigurationFile(@"applicationhost.config")
            .With(Project.Named("WindowsAuthSampleApp"));

        config.UseBrowser(BrowserDriver.InternetExplorer);

        _host = new SpecsForIntegrationHost(config);            
        _host.Start();
    }

    [TearDown]
    public void TearDown()
    {
        _host.Shutdown();
    }
}

Now you can write a spec!  In my sample, I had the view output the name of the current user, which should match the current Windows Identity at runtime.

public class HomeControllerSpecs
{
    public class when_viewing_the_home_page : SpecsFor<MvcWebApp>
    {
        protected override void When()
        {
            SUT.NavigateTo<HomeController>(c => c.Index());
        }

        [Test]
        public void then_it_has_the_name_of_the_logged_in_user()
        {
            SUT.FindDisplayFor<HomePageViewModel>()
                .DisplayFor(x => x.UserName).Text.ShouldEqual(WindowsIdentity.GetCurrent().Name);
        }
    }
}

Admittedly, this not nearly as easy nor as discoverable as it should be.  I’d really rather it be something like this:

var config = new SpecsForMvcConfig();
config.UseIISExpress()
    //.ApplicationHostConfigurationFile(@"applicationhost.config")
    .UseWindowsAuthentication()
    .With(Project.Named("WindowsAuthSampleApp"));

I’ve opened an issue for this on the Github project.  I’ll get to it eventually, but if someone would like to submit a pull request…. Smile 

The full source for this sample is available in the samples project on Github.

About Matt Honeycutt...

Matt Honeycutt is a software architect specializing in ASP.NET web applications, particularly ASP.NET MVC. He has over a decade of experience in building (and testing!) web applications. He’s an avid practitioner of Test-Driven Development, creating both the SpecsFor and SpecsFor.Mvc frameworks.

He's also an author for Pluralsight, where he publishes courses on everything from web applications to testing!

blog comments powered by Disqus