大约6个月前,我推出了一个网站,每个请求都需要通过https。当时我能找到的确保每个页面请求都是通过https的唯一方法是在页面加载事件中检查它。如果请求不是通过http,我会response.redirect("https://example.com")

有没有更好的方法,比如web。config中的一些设置?


当前回答

如果你不能在IIS中设置这个,我会做一个HTTP模块,为你重定向:

using System;
using System.Web;

namespace HttpsOnly
{
    /// <summary>
    /// Redirects the Request to HTTPS if it comes in on an insecure channel.
    /// </summary>
    public class HttpsOnlyModule : IHttpModule
    {
        public void Init(HttpApplication app)
        {
            // Note we cannot trust IsSecureConnection when 
            // in a webfarm, because usually only the load balancer 
            // will come in on a secure port the request will be then 
            // internally redirected to local machine on a specified port.

            // Move this to a config file, if your behind a farm, 
            // set this to the local port used internally.
            int specialPort = 443;

            if (!app.Context.Request.IsSecureConnection 
               || app.Context.Request.Url.Port != specialPort)
            {
               app.Context.Response.Redirect("https://" 
                  + app.Context.Request.ServerVariables["HTTP_HOST"] 
                  + app.Context.Request.RawUrl);    
            }
        }

        public void Dispose()
        {
            // Needed for IHttpModule
        }
    }
}

然后将其编译为DLL,将其作为项目的引用添加到web.config中:

 <httpModules>
      <add name="HttpsOnlyModule" type="HttpsOnly.HttpsOnlyModule, HttpsOnly" />
 </httpModules>

其他回答

你需要做的是:

1)在web中添加一个键。配置,取决于生产或阶段服务器如下所示

<add key="HttpsServer" value="stage"/>
             or
<add key="HttpsServer" value="prod"/>

2)在Global内部。Asax文件添加如下方法。

void Application_BeginRequest(Object sender, EventArgs e)
{
    //if (ConfigurationManager.AppSettings["HttpsServer"].ToString() == "prod")
    if (ConfigurationManager.AppSettings["HttpsServer"].ToString() == "stage")
    {
        if (!HttpContext.Current.Request.IsSecureConnection)
        {
            if (!Request.Url.GetLeftPart(UriPartial.Authority).Contains("www"))
            {
                HttpContext.Current.Response.Redirect(
                    Request.Url.GetLeftPart(UriPartial.Authority).Replace("http://", "https://www."), true);
            }
            else
            {
                HttpContext.Current.Response.Redirect(
                    Request.Url.GetLeftPart(UriPartial.Authority).Replace("http://", "https://"), true);
            }
        }
    }
}

如果SSL支持在您的站点中不可配置(例如。应该能够打开/关闭https) -你可以在任何你希望保护的控制器/控制器动作上使用[RequireHttps]属性。

如果你不能在IIS中设置这个,我会做一个HTTP模块,为你重定向:

using System;
using System.Web;

namespace HttpsOnly
{
    /// <summary>
    /// Redirects the Request to HTTPS if it comes in on an insecure channel.
    /// </summary>
    public class HttpsOnlyModule : IHttpModule
    {
        public void Init(HttpApplication app)
        {
            // Note we cannot trust IsSecureConnection when 
            // in a webfarm, because usually only the load balancer 
            // will come in on a secure port the request will be then 
            // internally redirected to local machine on a specified port.

            // Move this to a config file, if your behind a farm, 
            // set this to the local port used internally.
            int specialPort = 443;

            if (!app.Context.Request.IsSecureConnection 
               || app.Context.Request.Url.Port != specialPort)
            {
               app.Context.Response.Redirect("https://" 
                  + app.Context.Request.ServerVariables["HTTP_HOST"] 
                  + app.Context.Request.RawUrl);    
            }
        }

        public void Dispose()
        {
            // Needed for IHttpModule
        }
    }
}

然后将其编译为DLL,将其作为项目的引用添加到web.config中:

 <httpModules>
      <add name="HttpsOnlyModule" type="HttpsOnly.HttpsOnlyModule, HttpsOnly" />
 </httpModules>

对于上面的@Joe,“这是给我一个重定向循环。在我添加代码之前,它工作得很好。有什么建议吗?——乔11月8日11月4点13分

这种情况也发生在我身上,我认为发生的情况是有一个负载均衡器在Web服务器前终止SSL请求。因此,我的Web站点总是认为请求是“http”,即使原始浏览器要求它是“https”。

I admit this is a bit hacky, but what worked for me was to implement a "JustRedirected" property that I could leverage to figure out the person was already redirected once. So, I test for specific conditions that warrant the redirect and, if they are met, I set this property (value stored in session) prior to the redirection. Even if the http/https conditions for redirection are met the second time, I bypass the redirection logic and reset the "JustRedirected" session value to false. You'll need your own conditional test logic, but here's a simple implementation of the property:

    public bool JustRedirected
    {
        get
        {
            if (Session[RosadaConst.JUSTREDIRECTED] == null)
                return false;

            return (bool)Session[RosadaConst.JUSTREDIRECTED];
        }
        set
        {
            Session[RosadaConst.JUSTREDIRECTED] = value;
        }
    }

I'm going to throw my two cents in. IF you have access to IIS server side, then you can force HTTPS by use of the protocol bindings. For example, you have a website called Blah. In IIS you'd setup two sites: Blah, and Blah (Redirect). For Blah only configure the HTTPS binding (and FTP if you need to, make sure to force it over a secure connection as well). For Blah (Redirect) only configure the HTTP binding. Lastly, in the HTTP Redirect section for Blah (Redirect) make sure to set a 301 redirect to https://blah.com, with exact destination enabled. Make sure that each site in IIS is pointing to it's own root folder otherwise the Web.config will get all screwed up. Also make sure to have HSTS configured on your HTTPSed site so that subsequent requests by the browser are always forced to HTTPS and no redirects occur.