I have an intranet project written in MVC 4 which uses Windows Authentication to authorise and authenticate users.
I need to add a 'Login as another user' functionality.
After some searching I found this solution which suggests returning a 401, and created the following Action (which is called using a form):
//
// POST: /Home/LogOut
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LogOut()
{
return new HttpUnauthorizedResult();
}
The Action gets called, and the browser pops up a username and password window, however as the result redirects back to the Action, a 401 is always returned.
How do I redirect the user back to the previous action, once they have logged in with the new credentials?
Is there a way to invalidate the credentials on the server side instead of just returning a 401?
People reverse engineered\decompiled some code from Sharepoint that happens to have this feature.
I tested it in an ASP.NET MVC 5
app and it's working as expected.
The code is based on decompiling the
Microsoft.TeamFoundation.WebAccess which has the "Sign in as a
different User" function.
public ActionResult LogOut()
{
HttpCookie cookie = Request.Cookies["TSWA-Last-User"];
if(User.Identity.IsAuthenticated == false || cookie == null || StringComparer.OrdinalIgnoreCase.Equals(User.Identity.Name, cookie.Value))
{
string name = string.Empty;
if(Request.IsAuthenticated)
{
name = User.Identity.Name;
}
cookie = new HttpCookie("TSWA-Last-User", name);
Response.Cookies.Set(cookie);
Response.AppendHeader("Connection", "close");
Response.StatusCode = 401; // Unauthorized;
Response.Clear();
//should probably do a redirect here to the unauthorized/failed login page
//if you know how to do this, please tap it on the comments below
Response.Write("Unauthorized. Reload the page to try again...");
Response.End();
return RedirectToAction("Index");
}
cookie = new HttpCookie("TSWA-Last-User", string.Empty)
{
Expires = DateTime.Now.AddYears(-5)
};
Response.Cookies.Set(cookie);
return RedirectToAction("Index");
}
Source:
Force Sign in as a different user while using Windows Authentication in asp.net
This method will always log the user out and redirect to the home page. I also added [AllowAnonymous]
to make sure everybody can access this method.
[AllowAnonymous]
public ActionResult LogOut()
{
HttpCookie cookie = Request.Cookies["TSWA-Last-User"];
cookie = new HttpCookie("TSWA-Last-User", string.Empty)
{
Expires = DateTime.Now.AddYears(-5)
};
Response.Cookies.Set(cookie);
Response.AppendHeader("Connection", "close");
Response.StatusCode = 401; // Unauthorized;
Response.Clear();
// redirect to home
Response.Write("<script type='text/javascript'>");
Response.Write("var getUrl = window.location; var baseUrl = getUrl.protocol + " +
"'//' + getUrl.host + '/' + getUrl.pathname.split('/')[1]; window.location.href = baseUrl; ");
Response.Write("</script>");
Response.End();
return RedirectToAction("Index");
}
For me, working this:
public ActionResult LogOut()
{
HttpCookie cookie = Request.Cookies["TSWA-Last-User"];
if(User.Identity.IsAuthenticated == false || cookie == null
{
string name = string.Empty;
if(Request.IsAuthenticated)
{
name = User.Identity.Name;
}
cookie = new HttpCookie("TSWA-Last-User", name);
Response.Cookies.Set(cookie);
Response.AppendHeader("Connection", "close");
Response.StatusCode = 401; // Unauthorized;
Response.Clear();
//should probably do a redirect here to the unauthorized/failed login page
//if you know how to do this, please tap it on the comments below
Response.Write("Unauthorized. Reload the page to try again...");
Response.End();
return RedirectToAction("Index");
}
cookie = new HttpCookie("TSWA-Last-User", string.Empty)
{
Expires = DateTime.Now.AddYears(-5)
};
Response.Cookies.Set(cookie);
return RedirectToAction("Index");
}
And in html
<a href="@Url.Action("LogOut", "Home")" class="logout"><i class="fa fa-fw fa-power-off"></i> Salir</a>
$(".logout").click(function () {
logOut();
});
function logOut() {
try {
document.execCommand("ClearAuthenticationCache");
} catch (e) { }
}