Как работает базовая аутентификация при работе с HttpListener?

StackOverflow https://stackoverflow.com/questions/570605

Вопрос

Это может показаться простым вопросом, но вернемся к протоколу Http 101.Но мне трудно понять, как работает базовая аутентификация.Я реализую службу Windows, и мне нужно, чтобы она была безопасной.Я хотел бы получить имя пользователя и пароль и аутентифицировать пользователя в пользовательском хранилище пользователей.Я также хочу свести к минимуму количество вызовов входа в систему, поскольку вызов входа в систему представляет собой вызов нашего SQL-сервера.То, что я начал до сих пор, выглядит примерно так:

Насколько я понимаю, функция UserAuthorized должна выполнить мой собственный вызов для входа в систему.Но я не хочу делать это каждый раз.Сохраняется ли базовая аутентификация, если вы вошли в систему, или существует поточно-безопасное решение для кэширования, которое мне следует изучить.

Ах да, я также хотел бы сделать так, чтобы при аутентификации пользователя объект создавался и поддерживался в потоке, чтобы прослушиватель мог ссылаться на последующие обратные вызовы для пользователя/соединения.Но поскольку ListenerCallback статичен, я не уверен, как это можно сделать.

Заранее спасибо за любую помощь, я очень ценю это и StackOverflow.

public void ThreadProc() {
    string uriPrefix = ConfigurationManager.AppSettings["ListenerPrefix"];
    HttpListener listener = new HttpListener();
    listener.Prefixes.Add(uriPrefix);
    listener.AuthenticationSchemes = AuthenticationSchemes.Basic;

    listener.Start();

    Console.WriteLine("Start listening on " + uriPrefix);
    Console.WriteLine("Press Control-C to stop listener...");

    while (listening) {
        IAsyncResult result = listener.BeginGetContext(new AsyncCallback(ListenerCallback), listener);
        result.AsyncWaitHandle.WaitOne();
    }
}

public static void ListenerCallback(IAsyncResult result) {
    HttpListener listener = (HttpListener)result.AsyncState;
    HttpListenerContext context = listener.EndGetContext(result);
    WebDavEngine engine = new WebDavEngine(context.User);

    context.Response.SendChunked = false;
    FileLogger.Level = LogLevel.Debug;

    engine.IgnoreExceptions = false;

    if (UserAutorized(context)) {
        try {
            engine.Run(context, listener.Prefixes);
            engine.CommitTransaction();
        } catch {
            engine.RollBackTransaction();
        } finally {
            engine.CloseConnection();
        }
    } else
        context.Response.StatusCode = 401;

    if (context.Response.StatusCode == 401)
        ShowLoginDialog(context, context.Response);

    try {
        context.Response.Close();
    } catch {
        // client closed connection before the content was sent
    }
}

private static bool UserAutorized(HttpListenerContext context) {
    HttpListenerBasicIdentity identity = (HttpListenerBasicIdentity)context.User.Identity;

    if (!identity.IsAuthenticated) {
        string username = identity.Name;

        // workaround for Windows Vista Basic authentication. User name may be submitted in the following format: Machine\User.
        int ind = username.LastIndexOf('\\');
        if (ind > 0)
            username = username.Remove(0, ind + 1);


        Console.WriteLine("Trying Authentication since identity is NOT authenticated");

        return false;
    } else {
        Console.WriteLine("identity.IsAuthenticated: " + identity.IsAuthenticated.ToString());
        return identity.IsAuthenticated;
    }            
}

РЕДАКТИРОВАТЬ: +1 только за документ, который действительно открыл мне глаза на структуру схем аутентификации и на то, как они работают.Если я не ошибаюсь, оказывается, что схема дайджеста может поддерживать «сеанс» или, по крайней мере, срок действия для повторной попытки моей пользовательской аутентификации.

Это было полезно?

Решение 2

Спасибо за спецификацию, я оценил ее.Мне удалось решить мою проблему, и она была связана не со спецификациями, а с проблемой дизайна/хостинга.

Другие советы

HTTP базовый требует учетные данные для входа в каждый запрос.HTTP не имеет понятия сеанса, поэтому вы не можете точно сказать, «вошел ли кто-то уже в систему».

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top