Обход проверки подлинности с помощью форм с автоматическим перенаправлением для входа в систему, как?

StackOverflow https://stackoverflow.com/questions/35322

Вопрос

Я пишу приложение, используя asp.net-mvc для развертывания на iis6. Я использую формы аутентификации. Обычно, когда пользователь пытается получить доступ к ресурсу без надлежащей авторизации, я хочу, чтобы он был перенаправлен на страницу входа. FormsAuth делает это для меня достаточно просто.

Проблема: теперь у меня есть доступ к действию через консольное приложение. Какой самый быстрый способ заставить это действие ответить с состоянием 401 вместо перенаправления запроса на страницу входа?

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

Примечание. В качестве теста я добавил это в свой global.asax, и он не пропустил аутентификацию форм:

protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
    HttpContext.Current.SkipAuthorization = true;
}
<Ч>

@Дейл и Энди

Я использую AuthorizeAttributeFilter, предоставленный в предварительном просмотре MVC 4. Это возвращает HttpUnauthorizedResult. Этот результат правильно устанавливает statusCode на 401. Проблема, насколько я понимаю, заключается в том, что asp.net перехватывает ответ (так как он помечен как 401) и перенаправляет на страницу входа, а не просто пропускает ее. Я хочу обойти этот перехват для определенных URL.

Это было полезно?

Решение

Хорошо, я работал над этим. Я создал собственный 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.

Другие советы

Может быть клуджем (и может даже не работать), но на вашей странице входа в систему посмотрите, если Request.QueryString [" ReturnUrl "]! = null и если это так, установите Response.StatusCode = 401 .

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

Вы написали свой собственный атрибут 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. Мне нужно будет посмотреть далее вызов, чтобы увидеть, где перехватывается исключение, потому что более скорее всего, именно там они делают редирект. Это функциональность, которую вы должны будете переопределить. Я не уверен, что вы можете сделать это еще, но я отправлю вам ответ, когда найду это и предоставлю вам решение, если Haacked не увидит это и не отправит это сам.

Я немного погуглил, и вот что я придумал:


    HttpContext.Current.Response.StatusCode = 401;

Не уверен, работает ли это или нет, я не проверял это. В любом случае, стоит попробовать, верно? :)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top