/// <summary> /// Redirects to the specified URL. /// </summary> /// <param name="response">The response to use for redirection.</param> /// <param name="url">The URL to redirect to.</param> /// <param name="bypassSecurityWarning">If set to <c>true</c> security warnings will be bypassed.</param> public void Redirect(HttpResponseBase response, string url, bool bypassSecurityWarning) { if (bypassSecurityWarning) { Logger.Log("Bypassing security warning via a response header and JavaScript."); url = JsEncodeUrl(url); // Clear the current response buffer. response.Clear(); // Add a refresh header to the response for the new path. response.AddHeader("Refresh", "0;URL=" + url); // Also, add JavaScript to replace the current location as backup. response.Write("<html><head><title></title>"); response.Write("<script language=\"javascript\">window.location = '"); response.Write(url); response.Write("';</script>"); response.Write("</head><body></body></html>"); } else { Logger.Log("Issuing permanent redirect."); // Permanent redirect. // TODO: Make the status code configurable (i.e. permanent vs. temporary). response.StatusCode = 301; response.RedirectLocation = url; } // End the current response. response.End(); }
public void Enrich(HttpResponseBase response, HttpRequestBase request, ISecurityEvaluator securityEvaluator, Settings settings) { if (!securityEvaluator.IsSecureConnection(request, settings) || !settings.EnableHsts) { return; } // Add the needed STS header. response.AddHeader("Strict-Transport-Security", string.Format("max-age={0:f0}", settings.HstsMaxAge)); }
/// <summary> /// Gets any URI for the specified request that ensures it is being accessed by the proper protocol, if a match is found in the settings. /// </summary> /// <param name="request">The request to ensure proper access for.</param> /// <param name="response">The response to use if a redirection or other output is necessary.</param> /// <param name="security">The security setting to match.</param> /// <param name="settings">The settings used for any redirection.</param> /// <returns>A URL that ensures the requested resources matches the specified security; or null if the current request already does.</returns> public string GetUriForMatchedSecurityRequest(HttpRequestBase request, HttpResponseBase response, RequestSecurity security, Settings settings) { string targetUrl = null; // Evaluate the request's security. Logger.Log("Determining if the connection is secure."); bool isSecureConnection = _securityEvaluator.IsSecureConnection(request, settings); if (security == RequestSecurity.Secure && !isSecureConnection || security == RequestSecurity.Insecure && isSecureConnection) { Logger.Log("Calculating the target URI to switch to."); // Determine the target protocol and get any base target URL from the settings. string targetProtocolScheme; string baseTargetUrl; if (security == RequestSecurity.Secure) { targetProtocolScheme = Uri.UriSchemeHttps; baseTargetUrl = settings.BaseSecureUri; } else { targetProtocolScheme = Uri.UriSchemeHttp; baseTargetUrl = settings.BaseInsecureUri; } if (string.IsNullOrEmpty(baseTargetUrl)) { // If there is no base target URI, just switch the protocol scheme of the current request's URI. // * Account for cookie-less sessions by applying the application modifier. targetUrl = targetProtocolScheme + Uri.SchemeDelimiter + request.Url.Authority + response.ApplyAppPathModifier(request.RawUrl); } else { // Build the appropriate URI based on the specified target URL. var uri = new StringBuilder(baseTargetUrl); // - Use the full request path, but remove any sub-application path. uri.Append(request.RawUrl); if (request.ApplicationPath.Length > 1) { uri.Remove(baseTargetUrl.Length, request.ApplicationPath.Length); } // Normalize the URI. uri.Replace("//", "/", baseTargetUrl.Length - 1, uri.Length - baseTargetUrl.Length); targetUrl = uri.ToString(); } } return targetUrl; }