4

in my controller AuthController/signin i have this code:

    entities.UserAccount user = (new BLL.GestionUserAccount()).authentifier(email, password);
            //storing the userId in a cookie
            string roles = (new BLL.GestionUserAccount()).GetUserRoles(user.IdUser);
            // Initialize FormsAuthentication, for what it's worth

            FormsAuthentication.Initialize();

            //

            FormsAuthentication.SetAuthCookie(user.IdUser.ToString(), false);

            FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
            1, // Ticket version
            user.IdUser.ToString(), // Username associated with ticket
            DateTime.Now, // Date/time issued
            DateTime.Now.AddMinutes(30), // Date/time to expire
            true, // "true" for a persistent user cookie
            roles, // User-data, in this case the roles
            FormsAuthentication.FormsCookiePath);// Path cookie valid for

            // Encrypt the cookie using the machine key for secure transport
            string hash = FormsAuthentication.Encrypt(ticket);
            HttpCookie cookie = new HttpCookie(
               FormsAuthentication.FormsCookieName, // Name of auth cookie
               hash); // Hashed ticket



                // Get the stored user-data, in this case, our roles

            // Set the cookie's expiration time to the tickets expiration time
            if (ticket.IsPersistent) cookie.Expires = ticket.Expiration;

            // Add the cookie to the list for outgoing response
            Response.Cookies.Add(cookie);
            return RedirectToAction("index", "Home");

in the master page i have a menu ,in that menu there is an item that is meant to be seen only by admin role.

     <% if (HttpContext.Current.User.IsInRole("admin")){ %>

            <%=Html.ActionLink("Places", "Places", "Places")%>
        <%} %>

even with HttpContext.Current.User conatining the right roles,i can't see the item:

enter image description here

globalx asax:

    protected void Application_AuthenticateRequest(Object sender, EventArgs e)
    {
        if (HttpContext.Current.User != null)
        {
            if (HttpContext.Current.User.Identity.IsAuthenticated)
            {
                if (HttpContext.Current.User.Identity is FormsIdentity)
                {
                    FormsIdentity id =
                        (FormsIdentity)HttpContext.Current.User.Identity;
                    FormsAuthenticationTicket ticket = id.Ticket;

                    // Get the stored user-data, in this case, our roles
                    string userData = ticket.UserData;
                    string[] roles = userData.Split(',');
                    HttpContext.Current.User = new GenericPrincipal(id, roles);
                }
            }
        }
    }
  • Can you check if the `Current.User` role principal is properly created? – gideon Jan 24 '12 at 09:00
  • gideo ,check the image.my roles are there. –  Jan 24 '12 at 09:04
  • I know it sounds silly but thats your `userData` from your ticket. The only thing I can think if is if the `userData` is not going into the principal. (Possibly a problem with the last three lines of `glabal.asax`) Just a thought. – gideon Jan 24 '12 at 09:09
  • gideon,you are correct.there "admin " coming from my database.trim() has arranged things.Thank you.Should i delete the question? –  Jan 24 '12 at 09:21
  • haha! Was a wild guess but that't what I thought it was! =) No you don't need to delete the question (Infact you can't) It was a well written question and might be useful to someone. – gideon Jan 24 '12 at 09:23

6 Answers6

5

Instead of using User.IsInRole(), try the static method Roles.IsUserInRole().

Old Geezer
  • 14,854
  • 31
  • 111
  • 198
1

You will need a custom Authorize attribute which will parse the user data portion of the authentication ticket and manually create the IPrincipal. Take a look at this post which illustrates the way I would recommend you to do this in ASP.NET MVC. Never use HttpContext.Current in an ASP.NET MVC application. Not even in your views. Use <% if (User.IsInRole("admin")) { %> instead.

Community
  • 1
  • 1
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • 1
    @user594166, I have updated my answer with a link to an example of how I would recommend you proceed in an ASP.NET MVC application: http://stackoverflow.com/a/5476355/29407 It is a much more MVCish way to achieve this. – Darin Dimitrov Jan 24 '12 at 09:05
  • in what way it's MVCish? MyAuthorizeAttribute : AuthorizeAttribute? –  Jan 24 '12 at 09:13
  • @user594166, it's because in ASP.NET MVC you control authorization using action filters such as the [Authorize] attribute. And ni cases where you need to handle custom authorization as in your case you write a custom authorization attribute. Events in the global.asax such as Application_Request, Application_AuthenticateRequest, ... are used in classic web forms. In ASP.NET MVC there are more native ways to do that. – Darin Dimitrov Jan 24 '12 at 09:19
1

I know it sounds silly but from your image I can only see your userData from your ticket.

The only thing I can think if is if the userData is not going into the principal. (Possibly a problem with the last three lines of glabal.asax.cs)

Something is wrong here:

string userData = ticket.UserData;
string[] roles = userData.Split(',');
HttpContext.Current.User = new GenericPrincipal(id, roles);
gideon
  • 19,329
  • 11
  • 72
  • 113
0

One statement is missing.

After this line:

FormsAuthenticationTicket ticket = id.Ticket;

You need to put this line:

ticket = FormsAuthentication.Decrypt(ticket.Name);
0

In global.asax assign principal on 2 objects like that:

    private static void SetPrincipal(IPrincipal principal)
    {
        Thread.CurrentPrincipal = principal;
        if (HttpContext.Current != null)
        {
            HttpContext.Current.User = principal;
        }
    }

I found it here ASP.NET documentation

0

I had the same thing, but my cause was two-fold and not addressed by one of the answers listed above.

  1. This worked when I was connected to my corporate domain (on-prem or VPN) but not remote
  2. I tried adding a local permissions group with a matching name. It didn't help. Later, when I connected to my corporate domain, I was getting this error. My local permissions group had made things worse.
  3. I also tried @OldGeezer's answer, but Roles.IsUserInRole() seems to only work with local/forms authentication but not with domain/negotiate/digest.

Solution: If you are using domain/negotiate/digest authentication, confirm that you are connected to your domain (on-prem or vpn), confirm that the group (name) exists (check for spelling mistakes), make sure you don't have a local (pc) group with a conflicting name.

tgolisch
  • 6,549
  • 3
  • 24
  • 42