Как настроить проект mvc / webapi таким образом, чтобы метод webapi, вызываемый из вида бритвы, не возвращал страницу входа, если она не авторизована?
Это приложение MVC5, которое также имеет контроллеры WebApi для звонков через JavaScript.
Два метода ниже
[Route("api/home/LatestProblems")]
[HttpGet()]
public List<vmLatestProblems> LatestProblems()
{
// Something here
}
[Route("api/home/myLatestProblems")]
[HttpGet()]
[Authorize(Roles = "Member")]
public List<vmLatestProblems> mylatestproblems()
{
// Something there
}
Вызываются через следующий угловой код:
angular.module('appWorship').controller('latest',
['$scope', '$http', function ($scope,$http) {
var urlBase = baseurl + '/api/home/LatestProblems';
$http.get(urlBase).success(function (data) {
$scope.data = data;
}).error(function (data) {
console.log(data);
});
$http.get(baseurl + '/api/home/mylatestproblems')
.success(function (data) {
$scope.data2 = data;
}).error(function (data) {
console.log(data);
});
}]
);
Поэтому я не вошел в систему, и первый метод успешно возвращает данные. второй метод возвращает (в функции успеха) данные, которые содержат эквивалент страницы входа. то есть то, что вы получили бы в mvc, если бы вы запросили действие контроллера, помеченное [Authorize], и вы не вошли в систему.
Я хочу, чтобы он вернул 401 неавторизованным, чтобы я мог отображать разные данные для пользователей в зависимости от того, вошли они в систему или нет. В идеале, если пользователь вошел в систему, я хочу иметь возможность доступа к свойству пользователя контроллера, чтобы я мог возвращать данные, относящиеся к этому члену.
ОБНОВЛЕНИЕ: Поскольку ни одно из приведенных ниже предложений, похоже, больше не работает (изменения в Identity или WebAPI), я создал необработанный пример на github, который должен проиллюстрировать проблему.
Брок Аллен имеет хороший пост в блоге о том, как вернуть 401 для вызовов ajax при использовании аутентификации Cookie и OWIN. http://brockallen.com/2013/10/27/using-cookie-authentication-middleware-with-web-api-and-401-response-codes/
Поместите это в метод ConfigureAuth в файле Startup.Auth.cs:
источник
/api
, вы можете использовать этот путь, чтобы определить, следует ли перенаправить. Это особенно полезно, если у вас есть клиенты, которые используют другие форматы, такие как JSON. Заменить вызовIsAjaxRequest
сif (!context.Request.Path.StartsWithSegments(new PathString("/api")))
.private static bool IsAjaxRequest(IOwinRequest request) { return request.Query?["X-Requested-With"] == "XMLHttpRequest" || request.Headers?["X-Requested-With"] == "XMLHttpRequest"; }
Если вы добавляете asp.net WebApi на веб-сайт asp.net MVC, вы, вероятно, захотите ответить на некоторые запросы без разрешения. Но затем вступает в действие инфраструктура ASP.NET, и когда вы пытаетесь установить код статуса ответа HttpStatusCode.Unauthorized, вы получите 302 перенаправления на страницу входа.
Если вы используете идентификацию asp.net и аутентификацию на основе owin, вот код, который может помочь решить эту проблему:
источник
У меня возникла такая же ситуация, когда OWIN всегда перенаправляет ответ 401 на страницу входа из WebApi. Наш веб-API поддерживает не только вызовы ajax из Angular, но и вызовы Mobile, Win Form. Поэтому решение для проверки того, является ли запрос ajax-запросом, в нашем случае на самом деле не отсортировано.
Я выбрал другой подход - ввести новый заголовок ответа:
Suppress-Redirect
если ответы приходят из webApi. Реализация находится на обработчике:И зарегистрируйте этот обработчик на глобальном уровне WebApi:
Итак, при запуске OWIN вы можете проверить, имеет ли заголовок ответа
Suppress-Redirect
:источник
В предыдущих версиях ASP.NET вам приходилось делать кучу вещей, чтобы это работало.
Хорошей новостью является то, что вы используете ASP.NET 4.5. Вы можете отключить перенаправление проверки подлинности с помощью нового свойства HttpResponse.SuppressFormsAuthenticationRedirect .
В
Global.asax
:РЕДАКТИРОВАТЬ : Вы могли бы также хотеть взглянуть на эту статью Сергея Звездина, которая имеет более изощренный способ выполнить то, что вы пытаетесь сделать.
Соответствующие фрагменты кода и повествование автора вставлены ниже. Автор оригинального кода и повествования - Сергей Звездин .
Сначала - определим, является ли текущий HTTP-запрос AJAX-запросом. Если да, мы должны отключить замену HTTP 401 на HTTP 302:
Второе - давайте добавим условие :: если пользователь прошел аутентификацию, мы отправим HTTP 403; и HTTP 401 в противном случае.
Отлично сработано. Теперь мы должны заменить все использования стандартного AuthorizeAttribute этим новым фильтром. Это может быть неприменимо для тех парней, которые занимаются программированием. Но я не знаю другого пути. Если у вас есть, давайте перейдем к комментариям, пожалуйста.
Последнее, что нам нужно сделать - добавить обработку HTTP 401/403 на стороне клиента. Мы можем использовать ajaxError в jQuery, чтобы избежать дублирования кода:
Результат -
источник
Если вы запускаете свой
Web API
изнутри вашегоMVC
проекта, вам нужно создать кастом, которыйAuthorizeAttribute
будет применяться к вашимAPI
методам. ВнутриIsAuthorized
override
вам нужно захватить ток,HttpContext
чтобы предотвратить перенаправление, вот так:источник
При использовании интеграции с Azure Active Directory сам подход с использованием
CookieAuthentication
промежуточного программного обеспечения не работал для меня. Я должен был сделать следующее:Если запрос поступает от самого браузера (а не от вызова AJAX, например), тогда заголовок Accept где-то будет содержать строку
html
. Только когда клиент примет HTML, я буду считать перенаправление чем-то полезным.Мое клиентское приложение может обрабатывать 401, информируя пользователя о том, что приложение больше не имеет доступа и нуждается в перезагрузке для повторного входа в систему.
источник
У меня также было приложение MVC5 (System.Web) с WebApi (с использованием OWIN), и я просто хотел предотвратить изменение 401 ответа WebApi на 302 ответа.
Для меня работало создание настраиваемой версии WebApi AuthorizeAttribute следующим образом:
И использовать его вместо стандартного WebApi AuthorizeAttribute. Я использовал стандартный MVC AuthorizeAttribute, чтобы сохранить поведение MVC без изменений.
источник
SuppressFormsAuthenticationRedirect
флага заставила его просто вернуть существующий 401 для меня.Просто установите следующий пакет NeGet
Установочный пакет Microsoft.AspNet.WebApi.Owin
Запишите следующий код в файл WebApiConfig.
источник
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
противном случаеUser.Identity.IsAuthenticated
всегдаfalse
если вы хотите поймать Content-Type == application / json, вы можете использовать этот код:
С уважением!!
источник
Мне было трудно получить и код состояния, и текстовый ответ, работающий в методах OnAuthorization / HandleUnauthorizedRequest. Это оказалось лучшим решением для меня:
источник
После долгих хлопот, пытаясь избежать перенаправлений на страницу входа, я понял, что это на самом деле вполне подходит для атрибута Authorize. Это говорит иди и получить авторизацию. Вместо этого для вызовов Api, которые не авторизованы, я просто хотел не разглашать какую-либо информацию хакерам. Эту цель было проще достичь напрямую, добавив новый атрибут, полученный из Authorize, который вместо этого скрывает содержимое как ошибку 404:
источник
Смешивая MVC и WebAPI, если запрос не авторизован, он будет перенаправлен на страницу входа даже в запросе WebAPI. Для этого мы можем добавить код ниже, чтобы отправить ответ на мобильное приложение
источник
Спасибо, парни!
В моем случае я объединил ответы cuongle & Shiva и получил что-то вроде этого:
В обработчике OnException () контроллера для исключений API:
В конфигурационном коде запуска приложения:
источник
В MVC 5 с Dot Net Framework 4.5.2 мы получаем «application / json, обычный текст ..» под заголовком «Accept». Было бы хорошо использовать, как показано ниже:
источник