Регистрация пользователя при использовании HTTP-аутентификации

Я хочу, чтобы пользователи могли входить в систему через HTTP Основные режимы проверки подлинности.

Проблема в том, что я также хочу, чтобы они снова могли выйти из системы - странные браузеры, похоже, не поддерживают это.

Это считается риском для социального взлома - пользователь оставляет свою машину открытой и браузер открыт, а кто-то другой может легко посещать сайт как таковой. Обратите внимание, что закрытие вкладки-браузера недостаточно для reset токена, поэтому пользователям может быть легко пропустить.

Итак, я придумал обходной путь, но это полная сумка:

1) Перенаправить их на страницу выхода из системы

2) На этой странице выполните пожар script для ajax загрузите другую страницу с фиктивными учетными данными:

$j.ajax({
    url: '<%:Url.Action("LogOff401", new { id = random })%>',
    type: 'POST',
    username: '<%:random%>',
    password: '<%:random%>',
    success: function () { alert('logged off'); }
});

3) Это всегда должно возвращать 401 в первый раз (чтобы принудительно передать новые учетные данные), а затем принимать только фиктивные учетные данные:

[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) &&
        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");
}

4) Теперь учетные данные случайной строки были приняты и кэшированы браузером. Когда они посещают другую страницу, она будет пытаться использовать их, терпеть неудачу, а затем запрашивать правильные.

Обратите внимание, что в моих примерах кода используются jQuery и ASP.Net MVC, но то же самое должно быть возможно с любым стеком технологий.

В IE6 и выше есть другой способ сделать это:

document.execCommand("ClearAuthenticationCache");

Однако это очищает всю аутентификацию - они выходят из моего сайта, и они также выходят из электронной почты. Так что.

Есть ли лучший способ сделать это?

Я видел другие questions, но им 2 года - есть ли лучший способ теперь в IE9, FX4, Chrome и т.д.?

Если нет лучшего способа сделать это, на эту кладку можно положиться? Есть ли способ сделать его более надежным?

Ответ 1

Короткий anser:
Нет надежной процедуры для достижения "выхода из системы" с использованием HTTP Basic или Digest, учитывая текущие возможности базового auth.

Такая аутентификация работает, если клиент добавляет заголовок авторизации на запрос.
Если для определенного ресурса сервер не удовлетворен предоставленными учетными данными (например, если их нет), он ответит "401 Несанкционированный" код состояния и аутентификация запроса. Для этого он предоставит ответ WWW-Authenticate с ответом.

Клиенту не нужно ждать, пока сервер запрашивает аутентификацию. Он может просто предоставить заголовок авторизации на основе некоторых локальных предположения (например, кэшированная информация из последней успешной попытки).

В то время как ваш очерченный подход к "очистке" информации аутентификации имеет хорошие шансы работать с широким спектром клиентов (а именно, широко распространенными браузерами) нет абсолютно никакой гарантии, что более старый клиент может быть "умнее" и просто различайте правильные данные аутентификации для своей страницы выхода и любых других страниц целевого сайта.

Вы узнаете аналогичную "проблему" с использованием аутентификации на основе сертификата на стороне клиента. Пока нет явной поддержки со стороны клиентов, вы можете бороться с потерянным капиталом.

Итак, если проблема "выхода из системы" является проблемой, перейдите к любой проверке на основе сеанса.

Если у вас есть доступ к реализации аутентификации на стороне сервера, вы можете реализовать функциональность, которая будет игнорировать информацию аутентификации, представленную заголовком авторизации (если она по-прежнему идентична тому, что была представлена ​​во время текущего сеанса) по запросу вашего (или предоставить некоторое "время", после которого будут повторно запрошены любые учетные данные), чтобы клиент попросил пользователя предоставить "новые" учетные данные (выполнение нового входа).