Microsoft MVC 4, APIController и правильная веб-служба входа RESTful

Я сделал простую веб-службу RESTful (пока только для GET), используя Microsoft ASP.NET MVC 4 ApiController.

Сейчас ищу правильный способ реализации системы авторизации для сервиса. Я знаю, что не хочу использовать встроенный FormsAuthentication, так как не хочу иметь уникальную страницу входа для всех приложений, использующих мой WS; более того, это нарушает парадигму RESTful, вызывая перенаправление и не уведомляя клиента с правильным кодом состояния 401.

Поэтому я отключил FormsAuthentication, удалив следующие строки из моего web.config:

<authentication mode="Forms">
    <forms loginUrl="~/Account/Login" timeout="2880" />
</authentication>

и добавив следующее:

<modules runAllManagedModulesForAllRequests="true">
    <remove name="FormsAuthentication" />
</modules>

У меня уже есть ApiController для управления входом пользователя, который в основном проверяет учетные данные по моей базе данных и возвращает пользователя или 401, если учетные данные недействительны.

Я читал, что мне нужно реализовать Membership и Authorization API, но я не нашел ничего, что помогло бы мне сделать это с нуля. У тебя есть идеи? Нужно ли мне управлять файлами cookie и кодами авторизации в базе данных или есть класс, аналогичный FormsAuthentication, который сделает это за меня?


person frapontillo    schedule 28.03.2012    source источник


Ответы (3)


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

person Darin Dimitrov    schedule 28.03.2012

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

  1. Создайте папку с именем App_Start.
  2. Поместите два классы с соответствующими пространствами имен.
  3. FormsAuthentication и добавленная система обработки запросов/ответов сделают все остальное.

Так как мне не понравилось "Содержимое перемещено сюда" в моем ответе 401, я отредактировал метод OnEndRequest следующим образом:

private void OnEndRequest(object source, EventArgs args)
    {
        var context = (HttpApplication)source;
        var response = context.Response;

        if (context.Context.Items.Contains("__WEBAPI:Authentication-Fixup"))
        {
            response.StatusCode = (int)context.Context.Items[FixupKey];
            response.RedirectLocation = null;
            // Clear the page content, since I don't want the "Content moved here." body
            response.ClearContent();
        }
    }

Использованная литература:

person frapontillo    schedule 29.03.2012

Ознакомьтесь с этим проектом на github. Они разработали несколько классов с примерами для повышения безопасности веб-API ASP.NET. Одной из поддерживаемых моделей безопасности является базовая аутентификация, которую вы описываете в своем вопросе.

person Kevin Junghans    schedule 28.03.2012
comment
Похоже, мне нужен первый пример, BasicAuthentication. Но я еще не понял, есть ли способ сохранить код авторизации (я не буду отправлять имя пользователя и пароль клиенту в виде кода авторизации) в базе данных. - person frapontillo; 28.03.2012
comment
Я не уверен, что понимаю, что вы подразумеваете под способом хранения кода авторизации. Каково ваше описание кода авторизации. При базовой аутентификации вы хотите закодировать отправленное имя пользователя/пароль и расшифровать его на другом конце. Вы также хотите использовать HTTPS/SSL/TSL с базовой аутентификацией для шифрования всего сообщения в сети. При хранении паролей в БД я всегда использую одностороннее шифрование для сохраненного пароля. Затем вы используете то же шифрование для введенного пользователем пароля, прежде чем сравнивать то, что находится в БД. - person Kevin Junghans; 28.03.2012
comment
Я хотел бы создать временный код авторизации для каждого входа в систему и сохранить его в базе данных. Я думаю, что это то же самое, что и FormsAuthentication: он создает код авторизации сеанса, строго связанный с зарегистрированным пользователем. - person frapontillo; 28.03.2012
comment
Поясню лучше: если я загружу этот образец проекта, Microsoft и я запускаем веб-приложение, при первой регистрации оно автоматически создает базу данных по умолчанию с данными пользователя. Затем, когда я вхожу в систему, веб-приложение устанавливает файл cookie с именем .ASPXAUTH, который меняется каждый раз, когда я выхожу из системы. Это означает, что сервер проверяет значение cookie не по имени пользователя и паролю, а по сохраненному значению. Я хочу добиться того же, используя уже имеющуюся у меня таблицу User. - person frapontillo; 28.03.2012
comment
Я полагаю, вы описываете аутентификацию по токену, которая также поддерживается в библиотеке, о которой я упоминал ранее. В этом сообщении есть хорошее обсуждение соображений по использованию этого подхода [stackoverflow.com/questions/1432664/. По сути, вам нужно создать метод веб-службы для входа в систему, который возвращает токен (код авторизации), который клиент может использовать для любых дальнейших вызовов службы. При использовании этого метода вам необходимо добавить тайм-ауты в код авторизации. - person Kevin Junghans; 28.03.2012