only - asp.net c#redireccionando de http a https
redirigir http a https iis 7 (9)
Así que en mi código quiero detectar si mi página de inicio de sesión se llama http y redirigirla a https.
Sé que hay formas no codificadas para despellejar a este gato, pero por razones técnicas frustrantes estoy respaldado para hacerlo en código.
if (!Request.IsSecureConnection)
{
string redirectUrl = Request.Url.ToString().Replace("http:", "https:");
Response.Redirect(redirectUrl);
}
Así que Page_Load(...)
esto en mi Page_Load(...)
, me aseguro de que mi depurador use IIS real, no IIS de VS2008 y golpee la depuración.
En el depurador, sigue adelante, presiona Response.Redirect (" https://localhost/StudentPortal3G/AccessControl/AdLogin.aspx "), pulsa f5.
Obtener "Internet Explorere No se puede mostrar la página web, la URL es HTTP, no HTTPS. No se produce un error informativo ... sucede lo mismo y no se ejecuta en el depurador.
Entonces, ¿qué me estoy perdiendo? no parece ser ciencia espacial, he visto un código similar en muchos blogs ...
¿Qué estoy haciendo mal? Me imagino que tiene que ser un error de novato totalmente obvio, pero no lo estoy viendo.
Aquí está mi solución:
// 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();
}
Donde Settings.CanonicalDomain
es su nombre de host HTTPS. Redirige 301, lo que puede ser la respuesta adecuada en algunos casos.
En mi entorno de desarrollo, me gusta tener un directorio de publicación separado con IIS instalado con un certificado autofirmado, que es diferente al directorio de mi código sin un certificado que depuro directamente dentro de Visual Studio. En este escenario !Request.IsLocal
no es ideal porque no funciona en ningún lugar de su entorno de desarrollo, incluso en el directorio IIS con el certificado. Prefiero esto:
if (!IsPostBack && !HttpContext.Current.IsDebuggingEnabled)
{
// do http->https and https->http redirection here
}
HttpContext.Current.IsDebuggingEnabled
se basa en el valor de compilación debug = "true / false" en su web.config. Lo tengo configurado en verdadero en mi directorio de código, y falso en mi directorio de publicación cuando necesito probar la redirección de http y https localmente.
Agrego el IsPostBack
simplemente para hacerlo (ligeramente) más eficiente omitiendo la comprobación de SSL adicional cuando no es necesario.
En mi opinión, el siguiente es el mejor enfoque integral.
Tres razones
- Funciona tanto para
MVC
como para laWeb API
ya que se realiza a nivel deIIS
. - No afecta a la configuración local / depuración. (la redirección permanente puede alterarlo al depurar sitios que no sean
https
en su PC). - Utiliza una redirección permanente, por lo que todas las solicitudes futuras irán automáticamente a
https
Simplemente agregue lo siguiente a su sección <system.webServer>
en su ''Web.config'' para su proyecto.
<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>
Por lo general, llamo a lo siguiente desde OnPreInit en una clase base de la que todas mis páginas heredan. Por supuesto, puedes hacer esto en cada página ... pero no querrías hacerlo ahora, ¿verdad?
Tenga en cuenta que tengo dos propiedades para cada página, de modo que puedo especificar el requisito de SSL para cada página (RequiereSSL), mientras que también puedo anular y redirigir la comprobación si quiero (con IgnoreRequiresSSL, que es útil para páginas como páginas de error que usted reescriba y no sepa si estarán encriptados o no), pero por supuesto, puede eliminarlos para configuraciones 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);
}
También haría un !Request.IsLocal
para asegurarme de que no estoy depurando, aunque si está usando una instancia real de IIS con un certificado aplicado cuando se realiza la depuración, eso no debería ser un problema.
if (!Request.IsLocal && !Request.IsSecureConnection)
{
string redirectUrl = Request.Url.ToString().Replace("http:", "https:");
Response.Redirect(redirectUrl, false);
HttpContext.ApplicationInstance.CompleteRequest();
}
Nota: Esta respuesta asume un contexto MVC dentro de un Controlador donde HttpContext
es una propiedad que contiene el contexto actual. Si tiene la mala suerte de seguir usando WebForms o está haciendo referencia al contexto de forma degenerada, necesitará usar HttpContext.Current.ApplicationInstance.CompleteRequest()
.
Nota: He actualizado esto para que sea coherente con el patrón recomendado para terminar la solicitud de acuerdo con la documentación del marco .
Cuando use este método en un controlador de página para terminar una solicitud de una página e iniciar una nueva solicitud de otra página, establezca endResponse en false y luego llame al método CompleteRequest. Si especifica true para el parámetro endResponse, este método llama al método End para la solicitud original, que lanza una excepción ThreadAbortException cuando se completa. Esta excepción tiene un efecto perjudicial en el rendimiento de la aplicación web, por lo que se recomienda pasar el valor falso para el parámetro endResponse. Para más información, vea el método final.
También puedes usar el nuevo 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
DO#
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);
}
También sugeriría la solución de tvalfonsso, pero con una pequeña modificación en caso de que tenga alguna reescritura de URL (RawUrl difiere 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);
}
Una de las formas en que pude imponer una redirección de https es a la siguiente:
En el grupo de aplicaciones tengo mi aplicación ejecutándose solo en el puerto 443 para que no haya posibilidad de que se produzca una sesión sin cifrar (a menos que el esquema de encriptación se rompa a través de una vulnerabilidad ...). Creé otra aplicación en el puerto 80 con la misma dirección IP que contiene solo un archivo web.config con el siguiente código
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<httpRedirect enabled="true" destination="https://yourWebsiteURL.com" />
</system.webServer>
descargo de responsabilidad - participé en el desarrollo de este proyecto
Recomendaría usar http://nuget.org/packages/SecurePages/ Le brinda la posibilidad de proteger páginas específicas o usar Regex para definir coincidencias. También forzará que todas las páginas que no coincidan con Regex o que se especifiquen directamente a HTTP.
Puede instalarlo a través de NuGet: Install-Package SecurePages
Los documentos están aquí: https://github.com/webadvanced/Secure-Page-manager-for-asp.net#secure-pages
Uso simple:
SecurePagesConfiguration.Urls.AddUrl("/cart");
o
SecurePagesConfiguration.Urls.AddRegex(@"(.*)account", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline);