J'ai lu les précédents articles sur l'utilisation de RequireHttpsAttribute pour sécuriser des contrôleurs individuels:
ASP.NET MVC RequireHttps en production uniquement
mais existe-t-il un moyen d'appliquer cela à l'ensemble du site? En raison de mon hôte (discountasp.net), je ne peux pas utiliser le paramètre "RequireSSL IIS".
J'ai fini par utiliser IIS URL Rewrite 2.0 pour forcer le site à passer à HTTPS. Ce code dans web.config fait l'affaire:
<system.webServer>
<!-- This uses URL Rewrite 2.0 to force the entire site into SSL mode -->
<rewrite xdt:Transform="Insert">
<rules>
<rule name="Force HTTPS" enabled="true">
<match url="(.*)" ignoreCase="false" />
<conditions>
<add input="{HTTPS}" pattern="off" />
</conditions>
<action type="Redirect" url="https://{HTTP_Host}/{R:1}" appendQueryString="true" redirectType="Permanent" />
</rule>
</rules>
</rewrite>
</system.webServer>
Enregistrez la RequireHttpsAttribute
en tant que filtre global.
Dans global.asax:
protected void Application_Start()
{
GlobalFilters.Filters.Add(new RequireHttpsAttribute());
//... other stuff
}
Vous pouvez toujours ajouter une vérification au niveau de l'application dans votre global.asax
protected void Application_BeginRequest(Object sender, EventArgs e)
{
if (!HttpContext.Current.Request.IsSecureConnection)
{
Response.Redirect("https://" + Request.ServerVariables["HTTP_Host"]
+ HttpContext.Current.Request.RawUrl);
}
}
Juste pour apporter cette réponse à date pour MVC 3 et versions ultérieures, utilisez les éléments suivants dans votre fichier Filterconfig.cs dans le dossier App_start
filters.Add(new RequireHttpsAttribute());
Bien entendu, vous aurez besoin de configurer vos serveurs IIS pour utiliser un certificat SSL valide. Vous pouvez acheter des certificats bon marché à l’adresse suivante: https://www.namecheap.com/ / Je pense que la dernière fois que j’en ai acheté un, c’était 9 $ par domaine par an.
Dans votre FilterConfig.cs, appliquez ceci:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
// only if Debug is not enabled, do not require https for local development
if (!HttpContext.Current.IsDebuggingEnabled)
filters.Add(new RequireHttpsAttribute());
//... any other filters
}
Cela devrait forcer votre application à utiliser https sur chaque page.
Ceci n’utilise pas RequireHttps
mais je pense que c’est une meilleure solution car il intercepte la redirection plus tôt dans MVC Lifecycle .
public class RedirectModule : IHttpModule
{
private HttpApplication _context;
public void Init(HttpApplication context)
{
_context = context;
_context.PostResolveRequestCache += HttpRedirect;
}
public void HttpRedirect(Object src, EventArgs args)
{
if (_context.Request.Url.Scheme == Uri.UriSchemeHttp)
{
//Redirect to https
var scheme = Uri.UriSchemeHttps + "://";
var authority = _context.Request.Url.Authority;
var url = _context.Request.RawUrl;
var redirectTo = scheme + authority + url;
_context.Response.PermanentRedirect(redirectTo);
}
}
public void Dispose() { }
}
L'idée est venue de cet article article .
Vous pouvez enregistrer le module dans votre Web.config
ou à l'intérieur du Global.asax
. Je vais vous montrer dans le web.cofig.
<system.webServer>
<modules>
<add name="ConfigModuleName" type="Your.Namespace.RedirectModule"/>
</modules>
</system.webServer>
MVC 6 (ASP.NET Core 1.0) fonctionne légèrement différemment en ce qui concerne l’enregistrement des filtres:
Startup.cs - AddMvc avec filtre pour RequireHttpsAttribute :
public void ConfigureServices(IServiceCollection services)
{
// TODO: Register other services
services.AddMvc(options =>
{
options.Filters.Add(typeof(RequireHttpsAttribute));
});
}
Décisions de conception expliquées:
Si vous exécutez votre site Web MVC dans localhost sans SSL:
Envisagez de regarder comment exécuter sans SSL dans localhost tout en ayant besoin de https pour la production .
Remarque:
Comme alternative, nous pourrions créer une "classe BaseController: Controller" et faire en sorte que tous nos contrôleurs héritent de "BaseController" (au lieu de Controller). Ensuite, il suffit de définir l'attribut 1 global place (et il n'est pas nécessaire d'enregistrer le filtre dans Startup.cs).
Certaines personnes préfèrent le style d'attribut.
Exemple d'utilisation:
[RequireHttpsAttribute]
public class BaseController : Controller
{
// Maybe you have other shared controller logic..
}
public class HomeController : BaseController
{
// Add endpoints (GET / POST) for Home controller
}
Dans Global.asax.cs, utilisez "RegisterGlobalFilters" pour enregistrer les attributs globaux.
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new RequireHttpsAttribute());
//e.g. filters.Add(new HandleErrorAttribute());
//e.g. filters.Add(new System.Web.Mvc.AuthorizeAttribute());
}