Службы контроля доступа через IHttpModule с mvc 4 и web api, разные настройки безопасности для сайта и сервиса?

Я строю проект веб-API MVC 4 на Azure. Запросы к этому API идут по маршруту:

      routes.MapHttpRoute(
            name: "DefaultApi", // Route name
            routeTemplate: "api/{controller}/{id}", 
            defaults: new { id = RouteParameter.Optional }
      );

На том же домене и другом маршруте у меня настроен веб-сайт mvc:

      routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
      );

Веб-сайт mvc - это просто страница HTML и Javascript, которая взаимодействует со службами контроля доступа для получения токена, который затем передается службе для получения данных через jQuery ajax.

Чтобы реализовать безопасность служб (проверить токен, отправленный API), я использую классы SWTModule и TokenValidator, как описано в этой статье, а также вызов в моем проекте веб-приложения MVC 4 с атрибутом system.webserver проекта Web.Config:

<modules runAllManagedModulesForAllRequests="true">
  <add name="SWTModule" type="SecurityModule.SWTModule, SecurityModule" />
</modules>

Несмотря на то, что я не пометил методы контроллера MVC с помощью [Authorize], загрузка веб-страницы по умолчанию приводит к этой ошибке:

Ошибка сервера в приложении '/'

неразрешенный

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

Сведения об исключении: System.ApplicationException: неавторизовано

Ошибка источника:

Строка 43: Строка 44: // проверить, что она начинается с 'WRAP' Строка 45: if (! HeaderValue.StartsWith("WRAP ")) Строка 46:
{Строка 47: сгенерировать новое ApplicationException("не авторизовано");

Исходный файл: D:\Dev\VisualStudio2010\Projects\myServices\Azure\myDataInterfaces\SecurityModule\SWTModule.cs Строка: 45

Трассировки стека:

[ApplicationException: несанкционированный]
SecurityModule.SWTModule.context_BeginRequest (Отправитель объекта, EventArgs e) в D:\Dev\VisualStudio2010\Projects\myServices\Azure\myDataInterfaces\SecurityModule\SWTModule.cs:45 System.Web.SyncEventExecutionStepp.Exp. () +80 System.Web.HttpApplication.ExecuteStep(шаг IExecutionStep, логический и завершенный синхронно) +270

Мне кажется, что, хотя я не пометил свои методы Controller с помощью [Authorize], они отклоняются, потому что моя проверка токена SWT запускается для каждого ответа, предположительно потому, что он вызывается ранее в веб-стеке, из-за включения в атрибут Web.Config?

Может ли кто-нибудь указать мне правильное направление, как сделать эту работу? Я хочу сделать так, чтобы на веб-странице по умолчанию (метод индекса контроллера дома) отображался мой экран входа в систему, который затем перенаправлялся на главную страницу. Эта главная страница должна вернуться неавторизованным, если пользователь не вошел в систему с одним из доступных поставщиков удостоверений ACS. Точно так же я хочу оставить некоторые из моих методов ApiController Web API открытыми и требовать авторизацию для других.

В настоящее время у меня есть приложение MVC и служба веб-API, маршрутизируемые через один файл Global.asax в рамках одного проекта веб-приложения в одном решении для веб-роли в Visual Studio. Мне интересно, если способ исправить это, чтобы разделить сайт HTML MVC и веб-API на разные проекты веб-приложений в рамках одного решения веб-роли? Это все равно не дало бы мне средства для назначения требований авторизации для некоторых методов контроллера, просто дало бы мне другое место для маршрутизации контроллеров и ApiControllers.

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

Спасибо Алекс

2 ответа

Решение

Прежде всего, мне кажется, что ваш механизм авторизации создает исключение. Обычно вы возвращаете запрос со статусом 403 "Запрещено".

Правильный способ сделать это в Web API - создать DelegatingHandler а не модуль.

Взгляните на ThinkTecture Доминика Байера.

Также бесстыдная вилка.

В вашем посте есть несколько вопросов, поэтому вы точно не знаете, чего ожидаете. Я просто отвечу на ваш вопрос о том, почему модуль не работает, так как он кажется основным.

Да, SWTModule будет перехватывать все вызовы, объясняя причину сбоя при доступе к маршруту MVC. Модуль ничего не знает об атрибуте Authorize. Если вы хотите, чтобы это работало, вам лучше следовать совету Алиостада и использовать DelegatingHandler. Если вы хотите "просто" заставить его работать на данный момент, вы можете проверить путь выполнения запроса в модуле, чтобы он проверял только пути вашего API (обратите внимание, что это не будет работать для открытых методов API, так как модуль не работает). знать об атрибутах)

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

Опять же, это быстрый и грязный путь, чтобы заставить его работать, что может быть хорошо, если это POC использования ACS. В противном случае вам придется сделать еще домашнюю работу. Доминик написал несколько действительно хороших статей на эту тему. Ознакомьтесь со статьями "ASP.NET WebAPI Security от 1 до 4"

Другие вопросы по тегам