Damian Hickey

Mostly software and .NET related. Mostly.

Introducing Nancy.MSOwinSecurity

Under the Katana Project, Microsoft has released a suite of security related middleware including cookie and oauth based providers such as Google, Twitter etc. Nancy.MSOwinSecurity allows your Nancy application to work and interact with the Microsoft.Owin.Security.* middleware by giving you access to Microsoft.Owin.Security.IAuthenticationManager. From there you can access the CurrentUser as a ClaimsPrincipal, as well as perform various operations such as SignIn(), SignOut(), Challenge() etc.

How to use

Install the nuget package:

install-package Nancy.MSOwinSecurity

Getting the authentication manager and current user from the context:

public class MyModule : NancyModule
{
    public MyModule()
    {
        Get["/"] = _ =>
        {
            IAuthenticationManager authenticationManager = Context.GetAuthenticationManager();
            //ClaimsPrincipal user = authenticationManager.User;
            //authenticationManager.SignIn(..);
            //authenticationManager.SignOut(..);
            //authenticationManager.AuthenticateAsync(..);
            //authenticationManager.Challenge(..);
        };
    }
}

Securing a nancy module:

public class MyModule : NancyModule
{
    public MyModule()
    {
        this.RequiresMSOwinAuthentication();
        Get["/"] = _ => {...}
    }
}

Securing an individual route:

public class MyModule : NancyModule
{
    public MyModule()
    {

        Get["/"] = _ => 
        {
            this.RequiresMSOwinAuthentication();
            ....
        }
    }
}

Getting the current user (just a helper extension around IAuthenticationManager.User):

public class MyModule : NancyModule
{
    public MyModule()
    {

        Get["/"] = _ => 
        {
            ClaimsPrincipal = Context.GetMSOwinUser();
            ....
        }
    }
}

Authorizing the user at module level:

public class MyModule : NancyModule
{
    public MyModule()
    {
        this.RequiresSecurityClaims(claims => claims.Any(
            claim.ClaimType = ClaimTypes.Country &&
            claim.Value.Equals("IE", StringComparision.Ordinal)));
        Get["/"] = _ => 
        {
           ....
        }
    }
}

Authorizing the user at route level:

public class MyModule : NancyModule
{
    public MyModule()
    {

        Get["/"] = _ => 
        {
            this.RequiresSecurityClaims(claims => claims.Any(
                claim.ClaimType = ClaimTypes.Country &&
                claim.Value.Equals("IE", StringComparision.Ordinal)));
            ...
        }
    }
}

Personal note: this nancy extension package would integrate much better if we had extenstion properties in c# :(

Note: This package doesn't replace nor integrate with the exisiting nancy authentication and authorization infrasctructure (IUserIdentity). We're currently considering the best way to proceed on this.