Обход проверки подлинности с помощью форм с автоматическим перенаправлением для входа в систему, как? - PullRequest
6 голосов
/ 30 августа 2008

Я пишу приложение, используя 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.

Ответы [ 5 ]

5 голосов
/ 30 августа 2008

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

1 голос
/ 30 августа 2008

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

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

0 голосов
/ 30 августа 2008

Вы написали свой собственный атрибут FormsAuth для действия? Если это так, в методе OnActionExecuting вам передают FilterExecutingContext. Вы можете использовать это для возврата кода 401.

public class FormsAuth : ActionFilterAttribute
{
    public override void OnActionExecuting(FilterExecutingContext filterContext)
    {
        filterContext.HttpContext.Response.StatusCode = 401;
        filterContext.Cancel = true;
    }
}

Это должно работать. Я не уверен, что вы написали атрибут FormsAuth или получили его откуда-то еще.

0 голосов
/ 30 августа 2008

Я еще не использовал AuthorizeAttribute, который входит в Preview 4. Я свернул свой собственный, потому что я использую инфраструктуру MVC начиная с первого CTP. Я быстро взглянул на атрибут в рефлекторе, и он делает то, что упомянул выше, для внутреннего использования, за исключением того, что они используют шестнадцатеричный эквивалент 401. Мне нужно будет посмотреть далее вызов, чтобы увидеть, где перехватывается исключение, потому что скорее всего, именно там они делают редирект. Это функциональность, которую вы должны будете переопределить. Я не уверен, что вы можете сделать это еще, но я отправлю вам ответ, когда найду это и предоставлю вам решение, если Haacked не увидит это и не отправит это сам.

0 голосов
/ 30 августа 2008

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


    HttpContext.Current.Response.StatusCode = 401;

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

...