FubuMVC: Authentication

If you’re using FubuMVC and your site requires users to login, you’ll probably want to use the built in authentication facilities that FubuMVC provides. In this post, I’ll attempt to explain how this works.

I’m going to write an authentication convention to block access to certain actions from unauthenticated users.

Overview

  1. Come up with a convention to determine which action calls require the user to be authenticated
  2. Write a behavior to redirect a user if they’re not authenticated
  3. Teach FubuMVC about the convention
  4. Tell FubuMVC to use the convention
  5. Let FubuMVC know when someone has logged in or out

Step 1: Come up with a convention

For this example, my convention is going to be any action call marked with a [Secured] attribute, will require an authenticated user in order to execute. As you’ll see, this can be adapted to match whatever convention you want to use.

To start, I’ll just create a simple marker attribute and throw it on the action calls that I want to be secured.

Since we’ve marked the action calls that we want to secure, we’ll be able to pick them out later when we want to teach FubuMVC about our convention.

Step 2: Write a behavior

In order to do the actual work of checking to see if the user is logged in, and redirecting them if they’re not, I’ll need to create a behavior. If you’re unfamiliar with behaviors, I’d highly recommend reading these articles about them.

The behavior will depend on the ISecurityContext provided by FubuMVC, so I can check if the user has been authenticated. If the user has not been authenticated, I’ll just redirect them to the login page.

It’s important to note that, by default, the ISecurityContext is a wrapper around the current HttpContext. This means that FubuMVC is really just using standard ASP.NET forms authentication.

When FubuMVC calls the behavior, it will look at the result coming from the performInvoke() method. If the method returns DoNext.Continue, then the next behavior in the chain will be called. However, if it returns DoNext.Stop, then it will not call the next behavior in the chain and execution of the request stops. (It actually doesn’t just stop, if you’ve been through any behaviors that wrap the authentication behavior, you will begin to start calling the afterInsideBehavior method on these.

Step 3: Teach FubuMVC about the convention

So I’ve setup our action calls to use the convention and the behavior to kick unauthorized people out. Now I just need to teach FubuMVC what that convention is, and how it should be implemented. In order to do that, I’ll need to create an implementation of the IConfigurationAction interface (these are typically called conventions.) My convention will modify the graph and wrap all action calls that have the Secured attribute with our behavior.

In the convention, I have access to all of the Actions that FubuMVC knows about. I’m able to filter those actions to only get those which implement the SecuredAttribute, and then wrap those with the behavior I just created.

This is where I could change it up and use another convention if I wanted to. Instead of filtering the actions based on attributes, I can check for anything. If I wanted to filter for all actions with an input type that starts with “Add” or “Edit”, that’s possible by using this convention.

Step 4: Tell FubuMVC to use the convention

In order to tell FubuMVC to apply the convention, I need to call this method from the FubuRegistry.

Now, if I run my project and attempt to browse to an action that has been locked down, I get redirected to the login page, which is exactly what I wanted it to do.

Step 5: Let FubuMVC know when someone has logged in or out

In order to tell FubuMVC that a user has been logged in, I need to depend on IAuthenticationContext in the action that logs users in. Once I’ve verified the user’s credentials are correct, I can call the ThisUserHasBeenAuthenticated method on IAuthenticationContext to let FubuMVC know.

When I want to log a user out, call SignOut on the IAuthenticationContext interface.

Gotcha!

As I stated earlier, the default authentication in FubuMVC is really just a wrapper for forms authentication in ASP.NET. So, in order to use the ISecurityContext, you’ll need to turn on forms authentication in your web.config, otherwise the ISecurityContext will always say that the user is authenticated.

  • http://murrayon.net/ Mike Murray

    I imagine you could probably do PartialBehavior.Ignored instead of Executes in your AuthenticationRequiredBehavior constructor, as partial requests (if you even have any) will likely be a result of already existing full requests that have already run the authentication check you’ve just wired up. Not that this will make much of a difference (just some extra code run on partial requests), but it might give you a new feature to investigate if you’re new to FubuMVC or unfamiliar with that particular feature.

    • Anonymous

      Hey Mike, thanks for the tip. I didn’t really think about what I was passing in there. You’re right, you probably wouldn’t ever need to execute this on a partial request. I’ve updated the gist to use PartialBehavior.Ignored.

    • Anonymous

      @mkmurray:disqus I just argued in my head for a while to try and come up with a good counter example and I can’t.. Good catch.