Подтвердить что ты не робот

Аутентификация WebAPI + Forms + SimpleMembershipProvider с использованием WindowsIdentity, когда это не должно

Что я сделал

Я создаю приложение REST-ish WebAPI. Я пытаюсь реализовать аутентификацию форм здесь, поэтому клиенты могут разрешать пользователям входить в систему/регистрироваться/выходить из своих браузеров. Я использую simpleMembership, и пользователи хранятся в моих таблицах базы данных simpleMembership. В качестве первого шага я применил метод входа в свой аккаунт AccountsController:

    [System.Web.Http.HttpPost]
    public HttpResponseMessage LogIn(LoginModel model)
    {
        if (ModelState.IsValid)
        {
            if (User.Identity.IsAuthenticated)
            {
                return Request.CreateResponse(HttpStatusCode.Conflict, "already logged in.");
            }
            if (WebSecurity.Login(model.UserName, model.Password, persistCookie: model.RememberMe))
            {
                FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
                //TODO: look up by id, not by name
                var userProfile = _service.GetUser(WebSecurity.GetUserId(model.UserName));
                return Request.CreateResponse(HttpStatusCode.OK, userProfile);
            }
            else
            {
                return new HttpResponseMessage(HttpStatusCode.Unauthorized);
            }
        }

        // If we got this far, something failed
        return new HttpResponseMessage(HttpStatusCode.InternalServerError);
    }

Проблема

Вот что происходит:

  • Я установил точку останова в if (User.Identity.IsAuthenticated).
  • Используя что-то вроде POSTMan или Fiddler, я пытаюсь войти в систему, используя некоторые фиктивные учетные данные.
  • Я ударил точку останова и получил "Ложь" для IsAuthenticated, как и ожидалось.
  • Я перехожу к следующему "if", и попытка LogIn завершается с ошибкой, как и ожидалось.
  • Код в операторе else попадает, но после этого возвращается: 1) моя точка останова снова ударяется, а 2) у принципала установлен мой идентификатор Windows. Оба являются неожиданными, и я пытаюсь выяснить, как исправить это.

enter image description here

Ожидаемое поведение

  • Метод просто возвращает 401 Unauthorized, поскольку фиктивный пользователь не существует в моей базе данных приложений.

Конфигурация

Я думаю, что это проблема конфигурации. Принцип автоматически устанавливается на мою учетную запись Windows по какой-либо причине при сбое аутентификации. Некоторые подробности, связанные с моей конфигурацией:

<authentication mode="Forms">
  <forms loginUrl="~/" timeout="2880" />
</authentication>
  • Я не поддерживал проверку подлинности Windows в любом месте приложения. Мой web.config выше ^
  • Использование IISManager У меня отключена анонимная аутентификация
  • В моем приложении applicationhost.config отключена Windows и анонимная аутентификация

Вопросы

  • Почему точка останова ударяется дважды, вместо того, чтобы метод LogIn возвращался неавторизованным, так как это последнее "else" попало?
  • Почему мои учетные данные Windows используются для этого неожиданного и нежелательного "loopback"?
  • Как я могу предотвратить это? ИЛИ:
  • Нужно ли использовать MessageHandler для установки принципала? Если да, то как это влияет на [Аутентификация] и IsAuthenticated? Любые примеры?

Обновление 1

Я пробовал зарегистрировать следующий обработчик:

public class PrincipalHandler : DelegatingHandler
    {

        protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
                                                                               System.Threading.CancellationToken
                                                                                   cancellationToken)
        {
            HttpContext.Current.User = new GenericPrincipal(new GenericIdentity(string.Empty), null);
            Thread.CurrentPrincipal = HttpContext.Current.User;
            return await base.SendAsync(request, cancellationToken);
        }

    }

И теперь директор никогда не настроен на мой идентификатор Windows. Из POSTMan (расширение браузера) оператор if дважды попадает, и я получаю всплывающее окно с запросом учетных данных. Из Fiddler я просто получаю 401 Unauthorized, как и ожидалось.

Новые вопросы

  • Как я могу установить принципала в соответствии с тем, что в файле cookie ответа, И проверить подлинность моей простой таблицы членства в приложении?

Обновление 2

Кажется, что это сообщение приводит меня в правильном направлении - используя членство вместо User в моем LoginMethod:

ASP.NET MVC - установка пользовательского IIdentity или IPrincipal

Будет продолжать обновляться с прогрессом, но я по-прежнему открыт для предложений/рекомендаций.

Обновление 3 Я никогда не был так сдержан и разозлен - здесь не требовалось никакого специального обработчика. В моих свойствах проекта была включена авторизация Windows. Рабочее решение для входа и выхода из системы находится здесь и "просто работать" с моими таблицами членства:

public HttpResponseMessage LogIn(LoginModel model)
        {
            if (ModelState.IsValid)
            {
                if (User.Identity.IsAuthenticated)
                {
                    return Request.CreateResponse(HttpStatusCode.Conflict, "already logged in.");
                }
                if (WebSecurity.Login(model.UserName, model.Password, persistCookie: model.RememberMe))
                {
                    FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
                    return Request.CreateResponse(HttpStatusCode.OK, "logged in successfully");
                }
                else
                {
                    return new HttpResponseMessage(HttpStatusCode.Unauthorized);
                }
            }

            // If we got this far, something failed
            return new HttpResponseMessage(HttpStatusCode.InternalServerError);
        }

public HttpResponseMessage LogOut()
        {
            if (User.Identity.IsAuthenticated)
            {
                WebSecurity.Logout();
                return Request.CreateResponse(HttpStatusCode.OK, "logged out successfully.");
            }
            return Request.CreateResponse(HttpStatusCode.Conflict, "already done.");
        }
4b9b3361

Ответ 1

Используете ли вы IIS Express для разработки? Если это так, нажмите на свой проект в Visual Studio и проверьте окно свойств. Для проверки подлинности Windows существует опция, которая, по моему мнению, включена по умолчанию. Также отключите его.