Showing posts with label Security. Show all posts
Showing posts with label Security. Show all posts

Wednesday, May 4, 2011

Custom properties for IPrincipal

Sometimes you need to provide application specific values that are associated with a particular user. Let's say your application must handle role based security by using AD groups. Furthermore let's say that you wanted those group mappings to be configurable. A way to solve this would be to create your own implementation of IPrincipal. It might look something like this:

public class ApplicationPrincipal : IPrincipal
{
    private readonly IIdentity _identity;
    private readonly IPrincipal _principal;
    private readonly ISecurityConfiguration _config;

    public class ApplicationPrincipal(IIdentity identity, IPrincipal principal, ISecurityConfiguration config)
    {
        _identity = identity;
        _principal = principal;
        _config = config;
    }

    public IIdentity Identity { get { return _identity; } }

    public bool IsInRole(string role)
    {
        var windowsGroup = MapInternalRoleToWindowsGroup(role);
        return _principla.IsInRole(windowsGroup);
    }

    public string MapInternalRoleToWindowsGroup(string role)
    {
        switch (role)
        {
            case "Admin": return _config.AdminGroup;
            case "User": return _config.UserGroup;
            default: throw new SecurityException("Invalid group name: " + role);
        }
    }
}

Now that we have our own principal implementation we need a way to let the application access it. A good place to do that would be in an HttpModule that handles the PostAuthenticateRequest event.

public class ApplicationPrincipalModule : IHttpModule
{
    public void Init(HttpApplication context)
    {
        context.PostAuthenticateRequest += PostAuthenticateRequest;
    }

    public void Dispose()
    {
        context.PostAuthenticateRequest -= PostAuthenticateRequest;
    }

    private void PostAuthenticateRequest(object sender, EventArgs e)
    {
        var httpContext = HttpContext.Current;
        var principal = new ApplicationPrincipal(
                             httpContext.User.Identity, httpContext.User, 
                             new SecurityConfiguration());
        httpContext.User = principal;
    }
}

Once a user has been authenticated, by whichever method your application is set up to authenticate, this module will set the HttpContext.Current.User to your implementation of IPrincipal. This can then be referenced where needed in your application.