views:

118

answers:

1

I am currently trying to implement some custom security in an ASP.NET MVC2 web application.

I am trying to do something really simple as my code below shows but for some reason if I use the [Authorize(Roles="Admins")] attribute on one of my controller actions, check the Context.User.IsInRole("Admins") or Page.User.IsInRole("Admins") it is always false.

It is also weird that the User.Identity.Name is also blank.

See my code below, I am using a FormsAuthenticationTicket within a cookie which I then use in the Application_AuthenticateRequest event handle within my Gloabl.asax to set the Context.User with a GenericPrincipal object.

My login code:

[AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Login(string username, string password)
        {  

            //this would obviously do a check against the supplied username and password
            if (true)
            {
                FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, username, DateTime.Now,
                DateTime.Now.AddMinutes(15), false, "Admins|Users|Members");

                string encTicket = FormsAuthentication.Encrypt(ticket);

                HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);

                this.Response.Cookies.Add(cookie);
                string url = FormsAuthentication.GetRedirectUrl(username, false);

                Response.Redirect(url);               
            }


            return View();

        }

My Global.asax Code:

        void MvcApplication_AuthenticateRequest(object sender, EventArgs e)
        {
            HttpApplication application = (HttpApplication)sender;
            HttpContext context = application.Context;

            var cookie = context.Request.Cookies[FormsAuthentication.FormsCookieName];

            if (cookie != null)
            {                  

                // Get the authentication ticket 
                // and rebuild the principal & identity
                FormsAuthenticationTicket authTicket =
                  FormsAuthentication.Decrypt(cookie.Value);
                string[] roles = authTicket.UserData.Split(new Char[] { '|' });
                GenericIdentity userIdentity = new GenericIdentity(authTicket.Name);
                GenericPrincipal userPrincipal =
                    new GenericPrincipal(userIdentity, roles);

                context.User = userPrincipal;

            }

Once I set the context.User above I can view in the watch window and the object is set perfectly, in the correct roles with the right name etc, however if i try and lock down controller actions or use the Principal from anywhere in my site it is always set to an empty string with no roles assigned!!

I'm guessing i'm doing something really stupid here but if someone could point this out I would really appreciate it.

A: 

Check that you are assigning your new userPrincipal to both the HttpContext and the current thread within the OnPostAuthenticate request in global.asax:

HttpContext.Current.User = userPrincipal;
Thread.CurrentPrincipal = userPrincipal;
Clicktricity
@Clicktricity I've tried this and still no luck :(
MarkB29