Windows Azure Web Sites on MVA

The Windows Azure team has accelerated their deployment cadence, and to be honest, if you happened to look away for nine months, it’s like a whole ‘nother baby to deal with. For those not building solutions on WAWS, you’d be surprised at how much has changed, improved and increased in flexibility.

image

I’m privileged to get the chance to break it all down for you with Tejaswi Redkar, Director of Worldwide Communities at Microsoft. Join us live on Microsoft Virtual Academy on Thursday, December 12th (register here).

We’re bringing something to the table for everyone; for newcomers to WAWS you’ll get a peek at the Azure portal interface and gain a better understanding of the inner workings. Beyond the basic, we dive deep into everything from initial and continuous deployment right through to scaling your site up to support traffic growth. We also look at development off the .Net stack, including Node.js, and show you how to integrate with other aspects of Azure from your site.  Here’s the day at a glance:

  • Web Sites Overview
  • Know Thy Tools
  • Continuous Deployment
  • Scaling and Configuration
  • Go Live Checklist
  • Case Studies – Scale and Deployment
  • Lightning Round

Hope to catch you at the event…it’s free and easy to attend online!

Working With IAuthenticationFilter in the MVC 5 Framework

When implementing a custom authentication filter it’s important to know where in the pipeline your filter is invoked; if your purpose is to prevent unauthorized access to a controller action, be sure to implement your credentials verification early enough in the process. This post walks you through the creation of a basic authentication filter and shows the correct method in which to do the check. Good news: it’s easy!

We can learn a lot about the new IAuthenticationFilter interface by implementing one and seeing where it fits in the MVC pipeline.  Before we get started, let’s first remember that authentication and authorization are separate concerns in your application, so this filter is a welcome little addition.

Authentication is where a user provides credentials to access a resource, whereas authorization allows access to particular resources based on properties of the user’s identity. In previous versions of the MVC Framework we had the AuthorizeAttribute, which could be used to cause a redirect if you were unauthenticated, but it’s also true that it blurred the lines a little around auth & auth. 

Creating a Basic Do-Nothing Filter

Now that Authentication can more easily stand alone, the process to implement it is pretty simple:

  • Add a class to your project called NewAuthenticationFilter* Inherit from ActionFilterAttribute and IAuthenticationFilter
  • Implement the interface (click on the interface name and press Ctrl+. and hit enter)
  • Throw a couple of debug statements in so that we can set breakpoints, remembering to add the diagnostics namespace to your using statements

Just a few quick side notes on the above code.

  • I usually stick my filters into a Filters folder in my project (or into a separate DLL project to keep them reusable) to try to keep things clean
  • We inherit from ActionFilterAttribute so that we can use it as an attribute on our actions; just using IAuthenticationFilter isn’t enough
  • You can implement interface members by clicking on the interface name and pressing Ctrl+. and then tapping Enter

Your final class should look like the following:

public class NewAuthenticationFilter: ActionFilterAttribute, IAuthenticationFilter
{
public void OnAuthentication(AuthenticationContext filterContext)
{
Debug.WriteLine(“OnAuthentication”);
}

<span class="kwrd">public</span> <span class="kwrd">void</span> OnAuthenticationChallenge(AuthenticationChallengeContext filterContext)
{
    Debug.WriteLine(<span class="str">"OnAuthenticationChallenge"</span>);
}

}

With that in place, go the the Index action on the HomeController and add the attribute to the method. This will let the events fire as the request is processed. Also, set a breakpoint on the return statement. Your action should look like this:

[NewAuthenticationFilter]
public ActionResult Index()
{
return View();
}

Great! Let’s hit F5 and see what happens:

  • The OnAuthentication method is invoked, press F5 to continue
  • The action is executed, press F5 to continue
  • The OnAuthenticationChallenge is called last

Perfect, some of how we can use this is now becoming apparent. First of all, it’s important to note that the action can be fully executed before the OnAuthenticationChallenge is executed. This means that if you’re intending on preventing any DB writes or calls to something mutable or executable during the action, you’ll need to implement logic in OnAuthentication method to prevent this (we’ll get to that in a minute).

Second, both methods allow you to evaluate request information and set properties of the response, such as the Result (an ActionResult), but remember that the Action itself has the ability to set some of these properties and might overwrite what you set up in OnAuthentication (which, again, is called before the index action method in our example).

Finally, remember that this is just one part of the pipeline. The Result of the action hasn’t yet been executed when OnAuthenticationChallenge is complete, so something like a View hasn’t been rendered, or a FileResult that would load data from disk hasn’t yet been called.

But Wait! What is This All For?

I’m so glad you asked. Here’s the thing…Debug statements aren’t that interesting and don’t really show you how this can come into context. The user passes through the above code and our action is executed, as is our result, so the user gets to see whatever they requested come back in their browser. Let’s update our code and take another look at how our application might use this.

An authentication filter doesn’t really do much for us if it’s not, oh, say, filtering for authentication, so let’s start by checking to see if our user is actually presenting some kind of credentials.

public void OnAuthentication(AuthenticationContext filterContext)
{
if (!filterContext.Principal.Identity.IsAuthenticated)
filterContext.Result = new HttpUnauthorizedResult();
}

This is the most basic form of a check. “The identity of the principal is not authenticated, so set the result to unauthorized, an HTTP 401 status code.” Now we’re cooking with peanut oil and our 401 will not let the user access the action until they satisfy whatever arguments you’d like them to fulfill.  To that end, you don’t only need to use the principal identity, you can use whatever you like, such as a tie-in to a third-party SSO provider in a mixed identity environment.

Next, we have to deal with the fact that someone who is unauthenticated tried to access a resource we were protecting. The way the Authorize attribute worked was just by letting that 401 we set above flow through the framework. In an MVC application the default mechanism for authentication is Forms, for which there is a default account controller and corresponding views added to our project. Thus, by simply letting the user “fall through” here, they will end up at the login page.  For the following code in your challenge method:

public void OnAuthenticationChallenge(AuthenticationChallengeContext filterContext)
{
// redirect the user to some form of log in
}

…the user will keep that 401 state through, and will ultimately be bounced back to the site’s login page.

image

So, in it’s simplest form as we’ve done above, authentication filters give us a way to remove Authorize attributes (separation of concerns) and mimic the behavior we were previously leveraging to force users to log in. But there’s more, right?

Practical Uses of Our New Custom Authentication Bestie

We get pretty good support with the Authorize attribute and our ability to create custom filters already, but if we agree that separation of concerns is important, we get a few benefits with the new Authentication filters and the timing with which their methods are fired.

###

Isolated Custom Authentication

One of the first possibilities is that you can now setup an action or controller to have a custom authentication mechanism, rather than using whatever the default is for the site. If you have an external provider (perhaps something legacy) that you can proxy credentials to, this might be one way you could approach this.

Customizing UI For Login

There may be some cases where you want to do something like augment credentials, or perhaps configure part of the application, or even let users log in with a single-use code. OnAuthenticationChallenge lets you configure the result, so you can route the user to whatever view you like in your application.

##

Things to Remember

I actually don’t have a lot of caveats to suggest here, but perhaps the most important bit to remember is that if you IAuthenticationFilter.OnAuthenticate fall through without a 401, you’re letting the user into the action. Your OnAuthenticateChallenge will still fire, but remember from the breakpoints set above (when we were just spitting out debug lines) that the action will fire and your code _will _be executed. Logging the user in at this point happens after the invocation…a worst case scenario would be on a POST where an update is happening.

Finally, remember that Authentication wraps Authorization and action execution, and the Authenticate method precedes your first opportunity to interact with the request pipeline when you use ActionFilterAttribute inheritance on its own.

Next Steps

It’s pretty easy to try this out! Why not give the following a try?

  • File –> New –> Project and give the exercise above a try
  • Think of other uses or scenarios where one could leverage this
  • Break out your custom authentication filters built on the old objects in older versions of the MVC Framework

Happy coding!

_Thanks to good friend David Paquette who reviewed and suggested updates on this post._

SignalR Resources

I’ve had the pleasure over the last few weeks of carrying on the discussion around real time web with folks in Calgary, Kitchener/Waterloo and most recently Saskatoon. It’s clear, from the questions that are coming up, that there is a real desire to help improve the user experience in mobile and business apps – it’s not just about web.

I’ve put together some of the resources that I presented as well as the code that I wrote during the sessions. Here they are:

A big thanks to the user groups and to Prairie Dev Con for having me out, and thanks to everyone who joined in the conversation!

Troubleshooting 400.x and 500 Errors for WCF OData Service Deployments

Running into 400 & 500 error messages for WCF OData Services can be tricky to get past and even harder to sort through the red herrings out there. Here’s a few tips to attack any error messages you might run into.

Sweet! All done your spanky new OData services using Entity Framework in the back end and you’re feeling pretty awesome because a) it was stupid-easy to get going, and, #2 you are now the happy owner of a JSON data source with querystring filtering capabilities. Only trouble is, that darned thing won’t tick on your deployment server.

Don’t sweat it. There’s a dozen things that can sideways, but they’re all easy to fix.

Check Your Pre-Requisites

If you’re going to host over HTTP, you’ll obviously have IIS installed, but make sure you light up all the right pieces. You’ll need .Net 3.0 and 4.5 installed and enabled. If you want HTTP activation, that may not be on by default.  This MSDN article will get you there.

Try the Catch-Alls

Some of the errors you’ll run into can most easily be solved by using what’s given to you for free.  Check the Windows Event logs and drill into the details

If you’re not seeing much fruit from those efforts, you can also configure your service to use the verbose mode of error detail. This will likely reveal the juiciest information and is as easy as adding one line of code to your InitializeService method, as follows:

config.UseVerboseErrors = true;

Double-Check Your Configuration

If you’ve moved from dev to test or prod, you’ll need to make sure you update your connection strings.  Nestled in several of those 400 error message are details about a problem connecting to the database or other insight related to your credentials or connections through EF in your EDMX.

Some Low Hanging Fruit

I’ve run into 500’s a couple times, no information, just “internal server error”. This was because the application pool wasn’t set up for the correct version of .Net. Use the Advanced settings for your site in IIS to choose the app pool, or navigate IIS to the Application Pools and create a new one that matches the version of .Net for your service.

If you get 404.3, this is likely related to missing either the correct .Net components or the WCF Activation components (see MSDN article).

401’s that I’ve seen have been permissions related, naturally as they’re 401’s. Smile Check your directory permissions if you’re doing something on the file system, and your DB credentials in your web.config. Remember that those EDMX’s have some funky formatting.

Learn More

If you’ve got a night to invest in yourself I highly recommend reading the deeper bits on WCF Data Services. If you get serious, you’ll want to look into:

An indispensible tool in your kit is LINQPad – a must have for working with WCF OData.

Incorrectly Specified Targets File Causes Grief When Opening Solutions in Multiple Versions of Visual Studio

Working with solutions under different versions of Visual Studio is a welcome feature that has, for the most part, gone very smoothly for me.  There are some common sense environmental limitations and the ability to open projects in different versions of VS doesn’t save you from missing tools (I use RazorGenerator, for example), but otherwise it’s been a treat.

However, last night I got snagged for about 20 minutes when I ran into the following error when trying to open a project:

The imported project “C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets” was not found. Confirm that the path in the declaration is correct, and that the file exists on disk.

Without getting too deep into the details (which you can read here), Visual Studio injects some properties to your project file in order to maintain compatibility of your project in different versions of VS. In my case, environmentally, my system wasn’t configured in a way that was compatible with the properties that were created in the process of opening the project originally.  The solution was to simply remove the following from the project file:

  <PropertyGroup>
<VisualStudioVersion Condition=”‘$(VisualStudioVersion)’ == ‘’”>10.0</VisualStudioVersion>
<VSToolsPath Condition=”‘$(VSToolsPath)’ == ‘’”>$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>

Is This a Miss?

I was a little frustrated by the process, especially because the error, while entirely accurate, couldn’t give me more details on how to fix it. Without some digging online and coming across Sayed’s blog, I wouldn’t have been able to resolve this.

In situations like this, I don’t want to have to fight my tools, and I’m including the code my tools generate as “tools” as well. A very simple fix would be to also insert a comment into the project file along with the property group describing the intent and perhaps a KB article link to give details on the subject.

Why Did You Run Into This?

I think it’s easy to see how this could happen in my scenario: I have multiple laptops with multiple OS’s running multiple versions of IDE’s. The OS and the IDE are sometimes betas or otherwise advance copies. My projects are created and opened in any combination of these. That said, I was unable to recreate this problem on Win7/8 using VS2010/2012.

Wrapping Up…

It seems that removing this element from the csproj was enough to satisfy the IDE. There are other solutions, such as copying in valid targets files from other working environments. As I’m using Visual Studio 2012 exclusively on this project going forward, removing the VisualStudioVersion and VSToolsPath properties from my project file is a solution that worked for me.