ASP.NET MVC Futures RequireSSL Attribute и Authorize Attribute вместе - PullRequest
3 голосов
/ 15 июля 2009

Кто-нибудь успешно использует атрибуты Authorize и RequireSSL (из MVC futures) вместе на контроллере? Я создал контроллер, для которого я должен применить правило, согласно которому пользователь должен войти в систему и использовать безопасное соединение для выполнения. Если пользователь не подключен к защищенному соединению, я хочу, чтобы приложение перенаправляло его на https, поэтому я использую Redirect = true в атрибуте RequireSSL. Код выглядит примерно так (CheckPasswordExpired - это мой доморощенный атрибут):

[Authorize]
[RequireSsl(Redirect = true)]
[CheckPasswordExpired(ActionName = "ChangePassword",
    ControllerName = "Account")]
[HandleError]
public class ActionsController : Controller
{
    ....
}

mysite.com / Actions / Index - это маршрут по умолчанию для сайта, а также страница по умолчанию для перенаправления на проверку подлинности с помощью форм.

Когда я перехожу на http://mysite.com,, я хочу получить пользователя, перенаправленного на безопасное соединение, и, поскольку они еще не аутентифицированы, на страницу входа. Я получаю сообщение об ошибке HTTP 400 (неверный запрос). Если я перехожу на http://mysite.com/Account/Login,, перенаправление работает, но ни у моего контроллера учетной записи, ни у метода входа в систему нет атрибута [Authorize].

У кого-нибудь есть опыт совместного использования этих двух атрибутов для достижения моей цели?

Спасибо!

1 Ответ

4 голосов
/ 15 июля 2009

Я использую оба из них с успехом. У вас есть атрибуты в вашем действии по умолчанию?

public class HomeController : BaseController
{
  [Authorize]
  [RequireSsl]
  public ActionResult Index ()
  {
  }
}

Кстати, я использую немного измененную версию, чем фьючерсы, чтобы я мог отключить SSL глобально:

[AttributeUsage (AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public sealed class RequireSslAttribute : FilterAttribute, IAuthorizationFilter
{
    public RequireSslAttribute ()
    {
        Redirect = true;
    }

    public bool Redirect { get; set; }

    public void OnAuthorization (AuthorizationContext filterContext)
    {
        Validate.IsNotNull (filterContext, "filterContext");

        if (!Enable)
        {
            return;
        }

        if (!filterContext.HttpContext.Request.IsSecureConnection)
        {
            // request is not SSL-protected, so throw or redirect
            if (Redirect)
            {
                // form new URL
                UriBuilder builder = new UriBuilder
                {
                    Scheme = "https",
                    Host = filterContext.HttpContext.Request.Url.Host,
                    // use the RawUrl since it works with URL Rewriting
                    Path = filterContext.HttpContext.Request.RawUrl
                };
                filterContext.Result = new RedirectResult (builder.ToString ());
            }
            else
            {
                throw new HttpException ((int)HttpStatusCode.Forbidden, "Access forbidden. The requested resource requires an SSL connection.");
            }
        }
    }

    public static bool Enable { get; set; }
}
...