Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC 3 Custom Authentication/Authorization

I have searched all over the internet and SO, and I have found some good stuff on this topic, but I have a few questions that I am still unsure about:

1) I am using Forms Authentication with a custom Authentication provider. So I use the Authorize attribute and the section in the web.config still, but basically when the FormsAuthenticationTicket does not exist, I redirect to a login page (specified in the web.config) which then utilizes the custom Authentication Provider to auth the user against a db and then issues the FormsAuthenticationTicket. Is this correct?

2) Should I be using a custom Authorize attribute or should I just inject a GenericPrincipal into the HttpContext from the Application_AuthenticateRequest event handler in the global.asax page? Or should I be using User.IsInRole insode of the controller actions?

I just need role based authorization, and I think my Authentication Scheme is pretty good.

Any pointers/advice?

Thanks, Sam

Edit

So from what I have read, the best option for this is to create a custom AuthorizeAttribute and override the AuthorizeCore.

So what I have done is this:

public class CustomAuthorize : System.Web.Mvc.AuthorizeAttribute
    {
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            if (httpContext.User.Identity.IsAuthenticated)
            {
                var model = AdminUserViewModel.FromJsonString(((FormsIdentity)httpContext.User.Identity).Ticket.UserData);
                httpContext.User = new GenericPrincipal(HttpContext.Current.User.Identity, model.SecurityGroups.Select(x => x.Name).ToArray());
            }
            return base.AuthorizeCore(httpContext);
        }

        protected override void HandleUnauthorizedRequest(System.Web.Mvc.AuthorizationContext filterContext)
        {
            //base.HandleUnauthorizedRequest(filterContext);
            filterContext.Result = new System.Web.Mvc.RedirectResult("/Authentication/NotAuthorized", false);
        }
    }

Simply inject a new principal/identity with the roles that are stored in the FormsAuthenticationTicket UserData property. Then let the base do the rest.

Does this seem to be OK?

Edit #2

I am a little weary of using the Application_AuthenticateRequest in the global.asax with IIS7, because of the integrated pipeline, every request fires that event, images, css, js...

Is this correct?

like image 407
Sam Avatar asked Oct 10 '11 19:10

Sam


1 Answers

1) I do the same thing.

2) I use Authorize attribute and Application_AuthenticateRequest event handler.

In Application_AuthenticateRequest event handler I do something like this:

    string[] roles = authenticationTicket.UserData.Split(',');

    if (Context.User != null)
        Context.User = new GenericPrincipal(Context.User.Identity, roles);

And at controller or action level I do something like this:

    [Authorize(Roles = "Admin, SuperAdmin")]
like image 117
Randy Burden Avatar answered Sep 26 '22 19:09

Randy Burden