views:

509

answers:

2

I have an ASP.Net MVC intranet site which uses Windows Authentication to know who is logged in (no anon browsing allowed). The first time the users visit, I collect some very basic information from them for their Contact object (such as name, email, country) which is then stored in the apps database.

I want to make the site role based, so I need to be able to assign each user a role (user, admin etc). I could do this using ADS groups, but this seems rather heavyweight. Can I use the SQL Membership services provided by ASP.Net to store their usernames and then the roles they belong to, or will I be forced to collect passwords etc (defeating the point of using Windows Authentication)? Also does this integrate with the ASP.Net MVC [Authorize] attribute?

+2  A: 

It is certainly the case in "normal" ASP.NET that you can use this combination (Windows authentication and SQL for Roles), so it should be possible for MVC too.

Here's a link that might help.

RichardOD
Very interesting link, thanks Richard.
Colin Desmond
+1  A: 

Yes, you can do this.

Authorize uses the IsInRole method of IPrincipal to determine if the user is within a given role.

You can switch out the default implementation of IPrincipal during the AuthenticateRequest event within Global.asax with your implementation that handles this your way.

Here's some sample code that might actually work and compile and not expose your website to attacks by hackers:

private void Application_AuthenticateRequest(object sender, EventArgs e)
{
    if (!Request.IsAuthenticated)
    {
        Context.User = new MyPrincipal { Identity = new MyIdentity 
                { Type = UserType.Inactive, Id = int.MinValue }};
        Thread.CurrentPrincipal = Context.User;
    }
    else
    {
        HttpCookie authCookie = Request.Cookies[
            FormsAuthentication.FormsCookieName];
        if (authCookie != null)
        {
            FormsAuthenticationTicket authTicket =
                   FormsAuthentication.Decrypt(authCookie.Value);

            var identity = Db.GetIdentity(
              authTicket.Name, new HttpRequestWrapper(Request));
        Context.User = new MyPrincipal { Identity = new MyIdentity 
                { Type = UserType.Inactive, Id = int.MinValue }};
        Thread.CurrentPrincipal = Context.User;
        }
    }
}
Will
Thanks Will, I'll give it a go!
Colin Desmond