Я пишу приложение, используя развертывание asp.net-mvc на iis6. Я использую проверку подлинности с помощью форм. Обычно, когда пользователь пытается получить доступ к ресурсу без надлежащей авторизации, я хочу, чтобы он был перенаправлен на страницу входа. FormsAuth делает это для меня достаточно легко.
Проблема: теперь у меня есть действие, к которому обращается консольное приложение. Какой самый быстрый способ заставить это действие ответить со статусом 401 вместо перенаправления запроса на страницу входа?
Я хочу, чтобы консольное приложение могло реагировать на этот код состояния 401 вместо того, чтобы быть прозрачным. Я также хотел бы сохранить значение по умолчанию, перенаправлять неавторизованные запросы на поведение страницы входа.
Примечание: в качестве теста я добавил это в свой global.asax, и он не обходил формы auth:
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
HttpContext.Current.SkipAuthorization = true;
}
@ Дейл и Энди
Я использую AuthorizeAttributeFilter, предоставленный в предварительном просмотре MVC 4. Это возвращает HttpUnauthorizedResult. Этот результат правильно устанавливает statusCode на 401. Проблема, насколько я понимаю, в том, что asp.net перехватывает ответ (поскольку он помечен как 401) и перенаправляет на страницу входа, а не просто пропускает его. Я хочу обойти этот перехват для определенных URL.





Я немного погуглил, и вот что я придумал:
HttpContext.Current.Response.StatusCode = 401;
Не уверен, работает это или нет, я не тестировал. В любом случае, попробовать стоит, правда? :)
Вы написали свой собственный атрибут FormsAuth для действия? Если да, то в методе OnActionExecuting вам передается FilterExecutingContext. Вы можете использовать это, чтобы передать код 401.
public class FormsAuth : ActionFilterAttribute
{
public override void OnActionExecuting(FilterExecutingContext filterContext)
{
filterContext.HttpContext.Response.StatusCode = 401;
filterContext.Cancel = true;
}
}
Это должно сработать. Я не уверен, написали ли вы атрибут FormsAuth или получили его откуда-то еще.
Я еще не использовал AuthorizeAttribute из Preview 4. Я свернул свой собственный, потому что я использую фреймворк MVC с момента первого CTP. Я быстро взглянул на атрибут в отражателе, и он делает то, что я упомянул выше, внутри, за исключением того, что они используют шестнадцатеричный эквивалент 401. Мне нужно будет посмотреть дальше вызов, чтобы увидеть, где было обнаружено исключение, потому что больше, чем вероятно, именно там они и делают перенаправление. Это функциональность, которую вам нужно будет переопределить. Я не уверен, что вы можете это сделать, но я отправлю ответ, когда найду его, и предложу вам обходной путь, если только Хаакед не увидит это и не опубликует его сам.
Хорошо, я работал над этим. Я создал собственный ActionResult (HttpForbiddenResult) и пользовательский ActionFilter (NoFallBackAuthorize).
Чтобы избежать перенаправления, HttpForbiddenResult помечает ответы кодом состояния 403. FormsAuthentication не перехватывает ответы с этим кодом, поэтому перенаправление входа фактически пропускается. Фильтр NoFallBackAuthorize проверяет, авторизован ли пользователь, так же, как и включенный фильтр авторизации. Он отличается тем, что возвращает HttpForbiddenResult при отказе в доступе.
HttpForbiddenResult довольно тривиален:
public class HttpForbiddenResult : ActionResult
{
public override void ExecuteResult(ControllerContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
context.HttpContext.Response.StatusCode = 0x193; // 403
}
}
Не представляется возможным пропустить перенаправление страницы входа в FormsAuthenticationModule.
Я сделал то же самое. Этот парень в любом случае считает, что это правильно: danielirvine.com/blog/2011/07/18/understanding-403-forbidden
Это может быть кладж (и может даже не работать), но на странице входа в систему посмотрите, есть ли Request.QueryString["ReturnUrl"] != null, и если да, установите Response.StatusCode = 401.
Имейте в виду, что вам все равно нужно будет каким-то образом настроить консольное приложение для аутентификации. Вы не получаете базовую аутентификацию HTTP бесплатно: вам нужно использовать собственную, но существует множество реализаций.
Это не помогает по причинам, указанным TheDeeno.
См. stackoverflow.com/questions/2839406/…