2012-05-27 3 views
3

У меня есть веб-приложение MVC 4, где мне требуется SSL для определенного набора действий, и теперь мне бы хотелось, чтобы и процесс входа в систему был защищен SSL.как активировать SSL только для входа и определенных страниц MVC

После установки все, что происходит, так как параметр redirectToUrl на странице входа не указывает схему, все страницы, требующие входа, перенаправляются на https, независимо от атрибута [RequireHttps], который я установил (или, лучше сказать, не комплект) в действии.

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

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

Ссылка, которую я нашел в SO, - creating a custom attribute, чтобы украсить каждое действие, не требующее https, но есть ли что-нибудь более сухое, чем это?

+0

Хорошо, чтобы избежать повторения атрибута HttpsNotRequired, я мог бы использовать его для украшения базового контроллера, все еще задаваясь вопросом, есть ли более аккуратное решение. – eddo

ответ

2

Ну, я, наконец, выбрал для решения описанного в комментариях к моей должности, которая оказалась наиболее безболезненным подход.

Просто суммировать (все заслуги Лука Sampsons для кода, я просто перепроведении здесь для быстрой справки) это в основном код:

public class ExitHttpsIfNotRequiredAttribute : FilterAttribute, IAuthorizationFilter 
    { 
     public void OnAuthorization(AuthorizationContext filterContext) 
     { 
      // abort if it's not a secure connection 
      if (!filterContext.HttpContext.Request.IsSecureConnection) return; 

      // abort if a [RequireHttps] attribute is applied to controller or action 
      if (filterContext.ActionDescriptor.ControllerDescriptor.GetCustomAttributes(typeof(RequireHttpsAttribute), true).Length > 0) return; 
      if (filterContext.ActionDescriptor.GetCustomAttributes(typeof(RequireHttpsAttribute), true).Length > 0) return; 

      // abort if a [RetainHttps] attribute is applied to controller or action 
      if (filterContext.ActionDescriptor.ControllerDescriptor.GetCustomAttributes(typeof(RetainHttpsAttribute), true).Length > 0) return; 
      if (filterContext.ActionDescriptor.GetCustomAttributes(typeof(RetainHttpsAttribute), true).Length > 0) return; 

      // abort if it's not a GET request - we don't want to be redirecting on a form post 
      if (!String.Equals(filterContext.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase)) return; 

      // redirect to HTTP 
      string url = "http://" + filterContext.HttpContext.Request.Url.Host + filterContext.HttpContext.Request.RawUrl; 
      filterContext.Result = new RedirectResult(url); 
     } 
    } 
    public class RetainHttpsAttribute:FilterAttribute{} 

Атрибут ExitHttpsIfNotRequired может быть использован для украшения класс базового контроллера, используемый для вывода всех контроллеров в веб-приложении.

2

Я нашел следующее полезное, а не украшение с помощью [RequireHttps], которое я украшаю с помощью [Secure], а затем этот атрибут выполняет работу для меня.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Web.Mvc; 

namespace MyNameSpace.Attributes 
{ 
    public class SecureAttribute : ActionFilterAttribute 
    { 
     #region Variables and Properties 
     public bool PermanentRedirect { get; set; } 
     #endregion 

     #region Public Methods 
     public override void OnActionExecuting(ActionExecutingContext filterContext) 
     { 
      // Cache for efficiency 
      var request = filterContext.HttpContext.Request; 
      var response = filterContext.HttpContext.Response; 

      // Make sure we're not in https or local 
      if (!request.IsSecureConnection) 
      { 
       string redirectUrl = request.Url.ToString().Replace(
        Uri.UriSchemeHttp, 
        Uri.UriSchemeHttps); 

       if (PermanentRedirect) 
       { 
        // Set the status code and text description to redirect permanently 
        response.StatusCode = 301; 
        response.StatusDescription = "Moved Permanently"; 
       } 
       else 
       { 
        // Set the status code and text description to redirect temporary (found) 
        response.StatusCode = 302; 
        response.StatusDescription = "Found"; 
       } 

       // Add the location header to do the redirect 
       response.AddHeader("Location", redirectUrl); 
      } 

      base.OnActionExecuting(filterContext); 
     } 
     #endregion 
    } 
} 
+0

Ну, я так понимаю, я должен использовать этот атрибут, чтобы украсить действие входа. К сожалению, похоже, что это не помогает - после входа в систему страницы по-прежнему перенаправляются на https. Не уверен, использую ли я его, как вы его намереваетесь, в случае, если pls уточнит .. – eddo

+0

Возможно, вам понадобится модуль, который определяет, вошел ли пользователь в систему. Если он хранит их в https, если не перенаправляет их на http. Если пользователь вошел в систему, я бы хотел, чтобы вы хранили их в https для защиты будущих запросов? Или вы хотите, чтобы все перенаправлено на http после того, как логин завершился? –

Смежные вопросы