2

I have an MVC application that generally uses Basic Authentication. This allows us to change the application user to a different Active Directory user for cetain administrative functions. We do this by setting the response.StausCode = 401 thus :-

Response.Clear();
Response.StatusCode = (Int32)HttpStatusCode.Unauthorized;
Response.AddHeader("WWW-Authenticate", "Realm=Secured Site");
Response.AddHeader("Refresh", "0;");
Response.End();

This works fine but I am now trying to use Windows Authentication on the application but still allowing the user to be changed using the previous method. This again seems to work initially when the application is loaded (ie. navigate to site the select the 'changeuser' actionlink). The problem is that once you have navigated away from the index page clivking the 'changeuser' actionlink never prompts the user to login anymore even though the 401 has been set.

Any guidance appreciated.

Aran Mulholland
  • 23,555
  • 29
  • 141
  • 228
Parsley
  • 41
  • 1
  • 5
  • I'm pretty sure that the user agent caches basic HTTP credentials between requests - so when it gets the 401 it simply sends back the cached credentials the user entered previously - it has to send the credentials for every request anyway. – Antoine Latter Sep 12 '11 at 13:27
  • With Basic I get a login windows each time I set the statuscode = 401 this is what I want to happen with Windows Auth, if poss – Parsley Sep 12 '11 at 13:54

2 Answers2

1

You can do it, it does however require a bit of trickery. The code is based on decompiling the Microsoft.TeamFoundation.WebAccess which has the "Sign in as a different User" function, and refactoring to use MVC.

namespace WindwsAuthTest.Controllers {
   public class HomeController : Controller {
      public ActionResult Index() {
         ViewBag.Message = "Welcome to ASP.NET MVC!";
         return View();
      }

      public ActionResult About() {
         return View();
      }

      public ActionResult Logout() {
         return View();
      }

      public ActionResult SignInAsDifferentUser() {

         HttpCookie cookie = base.Request.Cookies["TSWA-Last-User"];

         if (base.User.Identity.IsAuthenticated == false || cookie == null || StringComparer.OrdinalIgnoreCase.Equals(base.User.Identity.Name, cookie.Value)) {

            string name = string.Empty;
            if (base.Request.IsAuthenticated) {
               name = this.User.Identity.Name;
            }

            cookie = new HttpCookie("TSWA-Last-User", name);
            base.Response.Cookies.Set(cookie);

            base.Response.AppendHeader("Connection", "close");
            base.Response.StatusCode = 0x191;
            base.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
            base.Response.Write("PageResources.UnauthorizedAccessMessage");
            base.Response.End();
            return RedirectToAction("Index");
         }

         cookie = new HttpCookie("TSWA-Last-User", string.Empty) {
            Expires = DateTime.Now.AddYears(-5)
         };
         base.Response.Cookies.Set(cookie);

         return RedirectToAction("Index");
      }
   }
}
Aran Mulholland
  • 23,555
  • 29
  • 141
  • 228
0

Surprisingly, it seems that browsers don't support this. I found this question for a friend asking a similar thing last June:

Logging a user out when using HTTP Basic authentication

He links to another question and the best answer is a little silly:

How to log out user from web site using BASIC authentication?

Basic Authentication wasn't designed to manage logging out. You can do it, but not completely automatically.

What you have to do is have the user click a logout link, and send a ‘401 Unauthorized’ in response, using the same realm and at the same URL folder level as the normal 401 you send requesting a login.

They must be directed to input wrong credentials next, eg. a blank username-and-password, and in response you send back a “You have successfully logged out” page. The wrong/blank credentials will then overwrite the previous correct credentials.

Community
  • 1
  • 1
Danny Tuppeny
  • 40,147
  • 24
  • 151
  • 275
  • Thanks Danny for your help. I have 'Basic Authentication' working pretty much as I want it, the problem arises with 'Windows Authentication' where I set the StatusCode to 401 but the login box does not appear – Parsley Sep 13 '11 at 09:51
  • I believe this is the same thing - the browser has cached the basic authentication so when it sees the 401 header it just sends the basic auth info again :-( – Danny Tuppeny Sep 13 '11 at 11:09