How do I determine and force users to view my website using HTTPS only? I know it can be done through IIS, but want to know how its done programmatically.
问题:
回答1:
You can write an HttpModule
like this:
/// <summary>
/// Used to correct non-secure requests to secure ones.
/// If the website backend requires of SSL use, the whole requests
/// should be secure.
/// </summary>
public class SecurityModule : IHttpModule
{
public void Dispose() { }
public void Init(HttpApplication application)
{
application.BeginRequest += new EventHandler(application_BeginRequest);
}
protected void application_BeginRequest(object sender, EventArgs e)
{
HttpApplication application = ((HttpApplication)(sender));
HttpRequest request = application.Request;
HttpResponse response = application.Response;
// if the secure connection is required for backend and the current
// request doesn't use SSL, redirecting the request to be secure
if ({use SSL} && !request.IsSecureConnection)
{
string absoluteUri = request.Url.AbsoluteUri;
response.Redirect(absoluteUri.Replace("http://", "https://"), true);
}
}
}
Where {use SSL}
is a some condition whether to use SSL or not.
EDIT: and, of course, don't forget to add a module definition to a web.config
:
<system.web>
<httpModules>
<!--Used to redirect all the unsecure connections to the secure ones if necessary-->
<add name="Security" type="{YourNamespace}.Handlers.SecurityModule, {YourAssembly}" />
...
</httpModules>
</system.web>
回答2:
A bit hard coded but straighforward!
if (!HttpContext.Current.Request.IsSecureConnection)
{
Response.Redirect("https://www.foo.com/foo/");
}
回答3:
You'd have to convert this from VB.NET to C#, but this is what I use in my sites:
Imports System.Web.HttpContext
Public Shared Sub SetSSL(Optional ByVal bEnable As Boolean = False)
If bEnable Then
If Not Current.Request.IsSecureConnection Then
Dim strHTTPS As String = "https://www.mysite.com"
Current.Response.Clear()
Current.Response.Status = "301 Moved Permanently"
Current.Response.AddHeader("Location", strHTTPS & Current.Request.RawUrl)
Current.Response.End()
End If
Else
If Current.Request.IsSecureConnection Then
Dim strHTTP As String = "http://www.mysite.com"
Current.Response.Clear()
Current.Response.Status = "301 Moved Permanently"
Current.Response.AddHeader("Location", strHTTP & Current.Request.RawUrl)
Current.Response.End()
End If
End If
End Sub
It's more code than some of the other techniques, but there's a reason for it. This method will only redirect when it's not in the mode it should be in. And when it does do a redirect, it does a 301 (permanent) redirection. The benefit there is that search engines will follow the 301 redirection and that will prevent any possibility of them indexing the same page twice (in http and https mode). You can compare this with the default behavior of Response.Redirect (302 temporary redirect) which Google, for example, doesn't treat the same way. They will not change their index based on a temporary redirect.
So if you're on a page that you want to be SSL-encrypted, call it like this:
SetSSL(True)
Otherwise:
SetSSL(False)
And if you really need this to be globally applied, I'd call SetSSL(True) in the Application_BeginRequest of your global.asax. Beware that SSL will slow things down a bit. For that reason I'm typically very selective when switching between http and https. In fact, out of dozens of sites I've developed there's only been two that use SSL throughout the entire site.
回答4:
This article covers moving requests in and out of SSL. Sometimes you dont want the user viewing a page in SSL because it burns proc cycles for pages that dont need to be secured.
http://weblogs.asp.net/kwarren/archive/2005/07/08/418541.aspx
回答5:
IIR you can check the request (HttpContext.Current.Request) for the domain which you then can check what protocol is being used (http,https, ftp, etc)
回答6:
You can also set up a rewrite rule in your web.config under the system.webServer
tag. eg:
<rewrite>
<rules>
<rule name="Redirect to HTTPS" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTP_HOST}" matchType="Pattern" pattern="^localhost(:\d+)?$" negate="true" ignoreCase="true" />
<add input="{HTTP_HOST}" matchType="Pattern" pattern="^127\.0\.0\.1(:\d+)?$" negate="true" />
<add input="{HTTPS}" pattern="off" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" />
</rule>
</rules>
</rewrite>