Note that there are some explanatory texts on larger screens.

plurals
  1. POLogging a user out when using HTTP Basic authentication
    primarykey
    data
    text
    <p>I want users to be able to log in via HTTP Basic authentication modes.</p> <p>The problem is that I also want them to be able to log out again - weirdly browsers just don't seem to support that.</p> <p>This is considered to be a social-hacking risk - user leaves their machine unlocked and their browser open and someone else can easily visit the site as them. Note that just closing the browser-tab is not enough to reset the token, so it could be an easy thing for users to miss.</p> <p>So I've come up with a workaround, but it's a total cludge:</p> <p>1) Redirect them to a Logoff page</p> <p>2) On that page fire a script to ajax load another page with dummy credentials:</p> <pre><code>$j.ajax({ url: '&lt;%:Url.Action("LogOff401", new { id = random })%&gt;', type: 'POST', username: '&lt;%:random%&gt;', password: '&lt;%:random%&gt;', success: function () { alert('logged off'); } }); </code></pre> <p>3) That should always return 401 the first time (to force the new credentials to be passed) and then only accept the dummy credentials:</p> <pre><code>[AcceptVerbs(HttpVerbs.Post)] public ActionResult LogOff401(string id) { // if we've been passed HTTP authorisation string httpAuth = this.Request.Headers["Authorization"]; if (!string.IsNullOrEmpty(httpAuth) &amp;&amp; httpAuth.StartsWith("basic", StringComparison.OrdinalIgnoreCase)) { // build the string we expect - don't allow regular users to pass byte[] enc = Encoding.UTF8.GetBytes(id + ':' + id); string expected = "basic " + Convert.ToBase64String(enc); if (string.Equals(httpAuth, expected, StringComparison.OrdinalIgnoreCase)) { return Content("You are logged out."); } } // return a request for an HTTP basic auth token, this will cause XmlHttp to pass the new header this.Response.StatusCode = 401; this.Response.StatusDescription = "Unauthorized"; this.Response.AppendHeader("WWW-Authenticate", "basic realm=\"My Realm\""); return Content("Force AJAX component to sent header"); } </code></pre> <p>4) Now the random string credentials have been accepted and cached by the browser instead. When they visit another page it will try to use them, fail, and then prompt for the right ones.</p> <p>Note that my code examples are using jQuery and ASP.Net MVC, but the same thing should be possible with any technology stack.</p> <p>There's another way to do this in IE6 and above:</p> <pre><code>document.execCommand("ClearAuthenticationCache"); </code></pre> <p>However that clears <em>all</em> authentication - they log out of my site and they're logged out of their e-mail too. So that's out.</p> <p>Is there any better way to do this? </p> <p>I've seen <a href="https://stackoverflow.com/questions/31326">other</a> <a href="https://stackoverflow.com/questions/233507">questions</a> on this, but they're 2 years old - is there any better way now in IE9, FX4, Chrome etc?</p> <p>If there is no better way to do this can this cludge be relied upon? Is there any way to make it more robust?</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload