Search code examples
asp.net-mvcasp.net-mvc-5windows-authentication

Retrieve Windows Identity after HttpUnauthorizedResult for IAuthenticationFilter


I have a IAuthenticationFilter will check the user group in SharePoint:

public class BasicAuthFilter : ActionFilterAttribute, IAuthenticationFilter
    {
        public void OnAuthentication(AuthenticationContext filterContext)
        {
            string userLoginName = filterContext.RequestContext.HttpContext.User.Identity.Name;
            if (SecurityManager.Auth(userLoginName))
                return;
            else
                filterContext.Result = new RedirectResult(new UrlHelper(filterContext.RequestContext).Action("AccessDenied", "Error"));
        }

        ...
    }
}

It will run on every request but except ErrorController

[AllowAnonymous]
public class ErrorController : Controller
    ...

    // Display view and link for "Logout"
    public ActionResult AccessDenied()
    {
        return View();
    }

    // GET: Logout
    [OutputCache(VaryByParam = "*", Duration = 0, NoStore = true)] // disable caching
    public ActionResult Logout()
    {
        string currentUser = User.Identity.Name;
        int AuthenticationAttempts = 0;

        if (Session["AuthenticationAttempts"] == null || !int.TryParse(Convert.ToString(Session["AuthenticationAttempts"]), out AuthenticationAttempts))
            AuthenticationAttempts = 0;

        AuthenticationAttempts += 1;

        if (AuthenticationAttempts == 1)
        {
            Session["PrevUser"] = User.Identity.Name;
            Session["AuthenticationAttempts"] = AuthenticationAttempts;
            return new HttpUnauthorizedResult();
        }
        else if (string.Compare(Convert.ToString(Session["PrevUser"]), currentUser, true) == 0)  // Somehow it will have echo back, ignore it
        {
            return new HttpUnauthorizedResult();
        }
        else
        {
            Session.Abandon();
            Session.Clear();
            return RedirectToAction("Index", "Home");
        }
    }
}

When the Error Controller return HttpUnauthorizedResult, the browser will prompt a login. And I can get the new user name from User.Identity.Name in ErrorController.

However, when it redirect to HomeController, the user was reset to original one, I tried following but still the same

filterContext.RequestContext.HttpContext.User.Identity.Name
filterContext.HttpContext.User.Identity.Name
filterContext.Principal.Identity.Name

Do I miss something or I should assign the principal after user input?


Solution

  • For anybody encounter the same issue, please make sure you have test it with IIS.

    This method work but cannot work in IISExpress.