user9677867
user9677867

Reputation:

Why does the authorize attribute fail to authorize the action with valid user being logged in?

I am using authorize attribute over an action.

[Authorize(Users= "admin" )]
[HttpGet]
public JsonResult GetServices()
{
    return Json(ServicesRepository.SelectServices(), JsonRequestBehavior.AllowGet);
}

While successfully logging in I am setting:

Session["Users"] = usersModels;                   
Session["UHTUserName"] = usersModels.UserName;
FormsAuthentication.SetAuthCookie(usersModels.UserName, LoginVM.RememberMe);

AuthorizeAttribute aattr = new AuthorizeAttribute();

aattr.Users = usersModels.UserName;

but still, it fails to authorize.

Upvotes: 0

Views: 1076

Answers (2)

Moses
Moses

Reputation: 11

Based on the above code snippet, you are using form authentication with MVC.

When Forms authentication is being used, whenever the need for authentication arises, the ASP.NET framework checks with the current IPrinciple type object. The user ID and Role contained in this IPrinciple type object will determine whether the user is allowed access or not.

So far you have not written code to push your user's Role details in this principle object. To do that you need to override a method called FormsAuthentication_OnAuthenticate in global.asax. This method is called each time ASP.NET framework tries to check authentication and authorization with respect to the current Principle.

What you need to do now is to override this method. Check for the authentication ticket (since the user has already been validated and the ticket was created) and then supply this User/Role information in the IPrinciple type object. To keep it simple, you will simply create a GenericPriciple object and set user specific details into it, as follows:

protected void FormsAuthentication_OnAuthenticate(Object sender, FormsAuthenticationEventArgs e)
{
    if (FormsAuthentication.CookiesSupported == true)
    {
        if (Request.Cookies[FormsAuthentication.FormsCookieName] != null)
        {
            try
            {
                //let us take out the username now                
                string username = FormsAuthentication.Decrypt(Request.Cookies[FormsAuthentication.FormsCookieName].Value).Name;
                string roles = string.Empty;

                using (userDbEntities entities = new userDbEntities())
                {
                    User user = entities.Users.SingleOrDefault(u => u.username == username);

                    roles = user.Roles;
                }
                //let us extract the roles from our own custom cookie


                //Let us set the Pricipal with our user specific details
                e.User = new System.Security.Principal.GenericPrincipal(
                  new System.Security.Principal.GenericIdentity(username, "Forms"), roles.Split(';'));
            }
            catch (Exception)
            {
                //somehting went wrong
            }
        }
    }
}

Note: In MVC 4 and later versions, this event will not work. To make the custom forms authentication work in MVC 4 and later versions, we need to put this code in Application_PostAuthenticateRequest event in the Global.asax file.

protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
{
    if (FormsAuthentication.CookiesSupported == true)
    {
        if (Request.Cookies[FormsAuthentication.FormsCookieName] != null)
        {
            try
            {
                //let us take out the username now                
                string username = FormsAuthentication.Decrypt(Request.Cookies[FormsAuthentication.FormsCookieName].Value).Name;
                string roles = string.Empty;

                using (userDbEntities entities = new userDbEntities())
                {
                    User user = entities.Users.SingleOrDefault(u => u.username == username);

                    roles = user.Roles;
                }
                //let us extract the roles from our own custom cookie


                //Let us set the Pricipal with our user specific details
                HttpContext.Current.User  = new System.Security.Principal.GenericPrincipal(
                  new System.Security.Principal.GenericIdentity(username, "Forms"), roles.Split(';'));
            }
            catch (Exception)
            {
                //somehting went wrong
            }
        }
    }
} 

Reference: https://www.codeproject.com/Articles/578374/AplusBeginner-splusTutorialplusonplusCustomplusF

Upvotes: 1

Hirav Sampat
Hirav Sampat

Reputation: 196

Did you set the settings in web.config for Forms Authentication

<system.web>
    <authentication mode="Forms"></authentication>
<system.web>

And while login set the cookie as follows

FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, //version                                                                                
UserName,      // user name                                                                               
DateTime.Now,        // create time                                                                                   
expiration,          // expire time                                                                                   
RememberMe,    // persistent                                                                                   
strUserData);        // user data/role

HttpCookie objHttpCookie = new HttpCookie(FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(ticket));

objHttpCookie.Path = FormsAuthentication.FormsCookiePath;
Response.Cookies.Add(objHttpCookie);

Upvotes: 0

Related Questions