1

good day!

now here's my issue in my project. everytime i log in it always redirect again in log in page. i tried to put a breakpoint in my controller and it happens that,at first log in when i login and click f10 in my controller it goes in all the condition. but when i log in at second it goes in the controller and in what role of that account was.

my codes:

account controller:

public ActionResult LogOn(LogOnModel model, string returnUrl)
        {
            if (ModelState.IsValid)
            {
                if (Membership.ValidateUser(model.UserName, model.Password))
                {
                    FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
                    if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
                        && !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
                    {
                        return Redirect(returnUrl);
                    }
                     if (Roles.IsUserInRole("Employer"))
                    {
                        return RedirectToAction("CustomerIndex", "Customer");
                    }
                     else if (Roles.IsUserInRole("Worker"))
                    {
                        return RedirectToAction("WorkerIndex", "Worker");
                    }
                     else if (Roles.IsUserInRole("Administrator"))
                     {
                         return RedirectToAction("ClientIndex", "Client");
                     }

                }
                else
                {
                    ModelState.AddModelError("", "The user name or password provided is incorrect.");
                }
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }

LogOn.cshtml:

@using (Html.BeginForm())
    {
        <div style="width: 500px;">
            <fieldset>
                <legend>Account Information</legend>
                <div class="editor-label" style="padding-top: 20px">
                    @Html.LabelFor(m => m.UserName)
                </div>
                <div class="editor-field">
                    @Html.TextBoxFor(m => m.UserName)
                    @Html.ValidationMessageFor(m => m.UserName)
                </div>
                <div class="editor-label">
                    @Html.LabelFor(m => m.Password)
                </div>
                <div class="editor-field">
                    @Html.PasswordFor(m => m.Password)
                    @Html.ValidationMessageFor(m => m.Password)
                </div>
                <div class="editor-label">
                    @Html.CheckBoxFor(m => m.RememberMe)
                    @Html.LabelFor(m => m.RememberMe)
                </div>
                <p>
                    <input type="submit" value="Log On" class="styledButton" />
                </p>
            </fieldset>
        </div>

    }

thank you. :D

Vinz with the Z
  • 157
  • 1
  • 14

1 Answers1

1

That is because the User has not yet been set in the HttpContext when executing that action (as you are logging in at that moment), so the calls to Roles.IsUserInRole will all return false, even if the user that is logging in belongs to that role.

Let's say that you are logging with a user that you know is member of the Administrator role. You can see it by yourself if you add the following debug statements to your LogOn method, right before checking roles for redirecting.

Debug.WriteLine("Controller user name: " + User.Identity.Name);
Debug.WriteLine("HttpContext user name: " + HttpContext.User.Identity.Name);
Debug.WriteLine(Roles.IsUserInRole("Administrator"));

You will see in the debug output window of Visual Studio that even after you have loggedin and set the auth cookie, the user name will be empty and IsUserInRole will return false.

However, when you submit the form again, as the user was already logged in (You just didn't redirected him to another page) the User is now set in the HttpContext. So, this time if you add those debug lines at the beginning of the LogOn method you would see in the output window the user name and that he is an administrator.

To fix your issue, the easiest thing to do would be using the IsUserInRole overload that lets you specify the user name, instead of relying in the HttpContext User. You would check the user roles as:

if (Roles.IsUserInRole(model.UserName, "Employer"))
{
    return RedirectToAction("CustomerIndex", "Customer");
}
else if (Roles.IsUserInRole(model.UserName, "Worker"))
{
    ...

You could also create a principal yourself and set it as the HttpContext.User before checking the user roles:

var curIdentity = new System.Security.Principal.GenericIdentity(model.UserName);
var curPrincipal = new System.Security.Principal.GenericPrincipal(curIdentity, null /*userRoles*/);
HttpContext.User = curPrincipal;
if (Roles.IsUserInRole("Employer"))
{
    return RedirectToAction("CustomerIndex", "Customer");
}
else if (Roles.IsUserInRole("Worker"))
{
    ...

However I would keep it simple and just pass the user name to the IsUserInRole method. For any other action in your application you can rely on the User automatically set for you in the HttpContext.

Daniel J.G.
  • 34,266
  • 9
  • 112
  • 112