Donc, dans mon code, je veux détecter si ma page de connexion s'appelle http et la rediriger vers https.
Je sais qu'il existe des moyens non codés pour habiller ce chat, mais pour une raison technique frustrante, je suis obligé de le faire en code.
if (!Request.IsSecureConnection)
{
string redirectUrl = Request.Url.ToString().Replace("http:", "https:");
Response.Redirect(redirectUrl);
}
Donc je laisse tomber ceci dans ma Page_Load(...)
, m'assure que mon débogueur utilise le vrai IIS, pas le VS2008s IIS, et frappe le débogage.
Dans le débogueur, valsez, appuyez sur Response.Redirect (" https: //localhost/StudentPortal3G/AccessControl/AdLogin.aspx "), appuyez sur f5.
Obtenir "Internet Explorere ne peut pas afficher la page Web, l'URL est HTTP, pas HTTPS. Pas d'erreur informative ... la même chose se produit ne fonctionne pas dans le débogueur.
Alors qu'est-ce qui me manque? cela ne semble pas être de la science des fusées, j'ai vu un code similaire sur de nombreux blogs ...
Qu'est-ce que je fais mal? Je pense que ce doit être une erreur de recrue totalement évidente, mais je ne le vois pas.
Je ferais aussi un !Request.IsLocal
Pour m'assurer que je ne débogue pas, bien que si vous utilisez une instance réelle de IIS avec un certificat appliqué lors du débogage qui ne devrait pas être un problème.
if (!Request.IsLocal && !Request.IsSecureConnection)
{
string redirectUrl = Request.Url.ToString().Replace("http:", "https:");
Response.Redirect(redirectUrl, false);
HttpContext.ApplicationInstance.CompleteRequest();
}
Remarque: Cette réponse suppose un contexte MVC dans un contrôleur où HttpContext
est une propriété contenant le contexte actuel. Si vous n'avez pas la chance de continuer à utiliser WebForms ou de référencer le contexte de manière dégénérée, vous devrez utiliser HttpContext.Current.ApplicationInstance.CompleteRequest()
.
Remarque: J'ai mis à jour cela pour être cohérent avec le modèle recommandé pour terminer la demande conformément à la documentation du framework .
Lorsque vous utilisez cette méthode dans un gestionnaire de pages pour terminer une demande pour une page et démarrer une nouvelle demande pour une autre page, définissez endResponse sur false, puis appelez la méthode CompleteRequest. Si vous spécifiez true pour le paramètre endResponse, cette méthode appelle la méthode End pour la demande d'origine, qui lève une exception ThreadAbortException lorsqu'elle se termine. Cette exception a un effet néfaste sur les performances des applications Web, c'est pourquoi il est recommandé de passer false pour le paramètre endResponse. Pour plus d'informations, voir la méthode End.
J'appelle généralement les éléments suivants à partir de OnPreInit dans une classe de base dont toutes mes pages héritent. Bien sûr, vous pouvez simplement le faire dans chaque page ... mais vous ne voudriez pas le faire maintenant, n'est-ce pas?
Notez que j'ai deux propriétés pour chaque page afin que je puisse spécifier l'exigence SSL pour chaque page (RequiertSSL) tandis que je peux également remplacer et rediriger la vérification si je veux (avec IgnoreRequiresSSL, ce qui est utile pour les pages comme les pages d'erreur que vous réécrire et ne savent pas s'ils seront chiffrés ou non), mais bien sûr, vous pouvez les supprimer pour des configurations simples.
protected override void OnPreInit(EventArgs e)
{
base.OnPreInit(e);
if (!IsPostBack)
RedirectAccordingToRequiresSSL();
...
}
/// <summary>
/// Redirect if necessary to ssl or non-ssl enabled URL dependant on RequiresSSL property setting.
/// </summary>
private void RedirectAccordingToRequiresSSL()
{
if (IgnoreRequiresSSL) return;
if (RequiresSSL)
{
if (!Request.IsSecureConnection) // Need to redirect to https
RedirectAccordingToRequiresSSL(Uri.UriSchemeHttps);
}
else if (Request.IsSecureConnection)
{
RedirectAccordingToRequiresSSL(Uri.UriSchemeHttp);
}
// Otherwise don't need to do any redirecting as already using the correct scheme
}
/// <summary>
/// Redirect as requested to specified scheme
/// </summary>
/// <param name="scheme"></param>
private void RedirectAccordingToRequiresSSL(string scheme)
{
var url = scheme + Uri.SchemeDelimiter + Request.Url.Authority + Request.Url.PathAndQuery;
Response.Redirect(url, false);
}
À mon avis, ce qui suit est la meilleure approche globale.
Trois raisons
MVC
et Web API
comme cela se fait au niveau IIS
.https
sur votre PC).https
Ajoutez simplement ce qui suit à votre <system.webServer>
section dans votre 'Web.config' pour votre projet.
<system.webServer>
....
<rewrite>
<rules>
<rule name="HTTP to HTTPS redirect" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTP_Host}" pattern="localhost" negate="true" />
<add input="{HTTPS}" pattern="off" ignoreCase="true" />
</conditions>
<action type="Redirect" url="https://{HTTP_Host}/{R:1}" redirectType="Permanent" />
</rule>
</rules>
<outboundRules>
<rule name="Add Strict-Transport-Security when HTTPS" enabled="true">
<match serverVariable="RESPONSE_Strict_Transport_Security" pattern=".*" />
<conditions>
<add input="{HTTPS}" pattern="on" ignoreCase="true" />
</conditions>
<action type="Rewrite" value="max-age=31536000" />
</rule>
</outboundRules>
</rewrite>
</system.webServer>
Vous pouvez également utiliser le nouveau UriBuilder:
Dim context As HttpContext = HttpContext.Current
If Not context.Request.IsSecureConnection Then
Dim secureUrl As New UriBuilder(context.Request.Url)
secureUrl.Scheme = "https"
secureUrl.Port = 443
context.Response.Redirect(secureUrl.ToString, False)
Return
End If
C #
HttpContext context = HttpContext.Current;
if (!context.Request.IsSecureConnection)
{
UriBuilder secureUrl = new UriBuilder(context.Request.Url);
secureUrl.Scheme = "https";
secureUrl.Port = 443;
context.Response.Redirect(secureUrl.ToString(), false);
}
L'une des façons dont j'ai pu appliquer une redirection https est la suivante:
Dans le pool d'applications, mon application s'exécute uniquement sur le port 443 afin qu'il n'y ait aucune possibilité qu'une session non cryptée se produise (sauf si le schéma de cryptage est rompu par une vulnérabilité ..). J'ai créé une autre application sur le port 80 avec la même adresse IP qui contient juste un fichier web.config avec le code suivant
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<httpRedirect enabled="true" destination="https://yourWebsiteURL.com" />
</system.webServer>
Je suggérerais également la solution de tvalfonsso, mais avec une petite modification au cas où vous auriez une réécriture d'URL (RawUrl diffère de Url)
if (SPPage == SPPages.StartAutotrading && !Request.IsLocal && !Request.IsSecureConnection)
{
string redirectUrl = (Request.Url.ToString().Replace(Request.Url.PathAndQuery.ToString(), "") + Request.RawUrl).Replace("http:", "https:");
Response.Redirect(redirectUrl);
}
Voici ma solution:
// Force HTTPS connection
if (!Request.IsSecureConnection)
{
var uri = new Uri(Request.Url.ToString());
var redirectUrl = Settings.CanonicalDomain + uri.PathAndQuery;
Response.Status = "301 Moved Permanently";
Response.AddHeader("Location", redirectUrl);
Response.End();
}
Où Settings.CanonicalDomain
est votre nom d'hôte HTTPS. Il 301 redirige ce qui peut être la réponse appropriée dans certains cas.
Mentions légales - J'ai participé au développement de ce projet
Je recommanderais d'utiliser http://nuget.org/packages/SecurePages/ Il vous donne la possibilité de sécuriser des pages spécifiques ou d'utiliser Regex pour définir des correspondances. Il forcera également toutes les pages ne correspondant pas au Regex ou directement spécifiées à HTTP.
Vous pouvez l'installer via NuGet: Install-Package SecurePages
Les documents sont ici: https://github.com/webadvanced/Secure-Page-manager-for-asp.net#secure-pages
Utilisation simple:
SecurePagesConfiguration.Urls.AddUrl("/cart");
ou
SecurePagesConfiguration.Urls.AddRegex(@"(.*)account", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline);
Sur mon environnement de développement, j'aime avoir un répertoire de publication séparé avec IIS installé avec un certificat auto signé, qui est différent de mon répertoire de code sans un certificat que je débogue directement à l'intérieur de Visual Studio. Dans ce scénario !Request.IsLocal
n'est pas idéal car il ne fonctionne nulle part sur votre environnement de développement, même dans le répertoire IIS avec le certificat. Je préfère ceci:
if (!IsPostBack && !HttpContext.Current.IsDebuggingEnabled)
{
// do http->https and https->http redirection here
}
HttpContext.Current.IsDebuggingEnabled
est basé sur la valeur de compilation debug = "true/false" dans votre web.config. Je l'ai défini sur true dans mon répertoire de code et sur false dans mon répertoire de publication lorsque j'ai besoin de tester la redirection http et https localement.
J'ajoute le IsPostBack
simplement pour le rendre (légèrement) plus efficace en sautant la vérification ssl supplémentaire lorsqu'elle n'est pas nécessaire.