|
|||||||||||||||||||||
|
|||||||||||||||||||||
|
Announcements
Want a new Job?
Chapters
Services
Feature Zones
|
Important: New VersionPlease refer to the new version of this module and article here: Switching Between HTTP and HTTPS Automatically: Version 2. IntroductionLet's face it. Providing sensitive information on a web site is a risk. Many visitors will not give out that kind of data even if they see that the web site claims security. Many more will certainly not reveal their personal details if the warm-and-fuzzy closed padlock isn't visible in their browser window. BackgroundEnter Secure Sockets Layer. SSL is a developer's tool for securing the transmission of data. Whether you are encrypting pages for the checkout area of an e-commerce site or you are protecting the personal statistics that your users supply you for marketing; SSL is ideal. A trusted certificate installed on the web server offers visitors, that good feeling of a secure environment. There are caveats when implementing a web site that makes use of the HTTPS protocol. I'm not referring to the technical nuances you, or a system administrator, must face when installing a certificate on the server. What about simply adding a link from one page to another page that should be secured? Those of you who have experience with writing web pages that use SSL probably know where I'm going with this. You cannot switch protocols unless you provide an absolute URL. Therefore, in order to allow a visitor to click on a link that should take them to a secure web page, the reference must be absolute. https://www.codeproject.com/secure/getsensitiveinfo.asp
To make things worse, many browsers download pages referenced by a relative URL with the same protocol as the last request. So, if you had a link in the above file to another page in the root directory, that you wanted to show with the HTTP protocol, it would also have to be absolute. <!--
The following will actually be translated as
https://www.codeproject.com/welcome.asp;
thus, retaining the HTTPS protocol that was last used.
-->
<a href="../welcome.asp">Back to the Welcome Page.</a>
Generally, it is not a good idea to encrypt every single page request with SSL. It makes for slower page serves and more bandwidth usage. It is also more intensive on the server's CPU; something your hosting provider may not be pleased with. A SolutionBeing forced to use absolute URLs for internal links in a web site is less than appealing. The next thing you know, the web site's domain name changes (for any number of reasons) or you have a staging server, which means you have to maintain a separate copy of the site for that set of absolute URLs. It makes much more sense to mark certain files and/or entire directories as "secure". This would allow you the benefit of using relative URLs freely within your web pages. If an existing page needs to be made secure, you simply add it to the list of marked files instead of finding and replacing all links to the page with an absolute URL. That's where The goal of this security solution is to allow a developer to easily secure a web site without the need to hard-code absolute URLs. This is accomplished by listing the files and/or directories that should be secured by SSL. It only seems natural to have a custom configuration section for this. ConfigurationSimply add a new section to the web.config file of the application to secure. Make sure you add this section outside of the <?xml version="1.0" encoding="utf-8" ?>
<configuration>
...
<secureWebPages enabled="true">
...
</secureWebPages>
...
<system.web>
...
</system.web>
</configuration>
Next, you need to specify any files and directories to include for automatic security. Files are added via What does that mean? All application requests are processed by the ...
<secureWebPages enabled="true">
<file path="Login.aspx" />
<file path="Lib/PopupCalendar.aspx" ignore="True" />
<file path="Members/ViewStatistics.aspx" />
<directory path="Admin" />
<directory path="Members/Secure" />
</secureWebPages>
...
The above example enables the The developer may have chosen to ignore the Lib/PopupCalendar.aspx file because that page is used by several other pages that have calendar icons which, when clicked, opens a pop-up window to the page, allowing the user to select a date. If one of these icons is clicked on a page that is not secure, the developer wouldn't want the Lib/PopupCalendar.aspx page to be served with SSL. On the other hand, if a calendar icon was clicked on a page in the Admin directory, the developer certainly would not want the Lib/PopupCalendar.aspx page to be presented via HTTP. The user would, most likely, be alerted by their browser that they were leaving a secure area to view the pop-up page. I think I can safely state that most users would lose any feeling of comfort after seeing a warning like that. The SecureWebPageSectionHandler ClassThe public object Create(object parent, object configContext,
XmlNode section)
{
// Create a SecureWebPageSettings object for the settings
// in this section
SecureWebPageSettings Settings = new SecureWebPageSettings();
// Get the enabled attribute
if (section.Attributes["enabled"] != null)
{
Settings.Enabled = (section.Attributes["enabled"].Value.ToLower()
!= "false");
}
if (Settings.Enabled)
{
// Traverse the child nodes
SecureWebPageCollection SecurePathList;
string Path;
bool Ignore;
foreach (XmlNode Item in section.ChildNodes)
{
if (Item.NodeType == System.Xml.XmlNodeType.Comment)
// Skip comment nodes (thanks to dcbrower
// on CodeProject for pointing this out)
continue;
else if (Item.Name.ToLower() == "directory")
// This is a directory path node
SecurePathList = Settings.SecureDirectories;
else if (Item.Name.ToLower() == "file")
// This is a file path node
SecurePathList = Settings.SecureFiles;
else
// Throw an exception for this unrecognized node
throw new SecureWebPageSectionException(string.Format(
"'{0}' is not an acceptable setting.",
Item.Name), Item);
// Get the path attribute value
if (Item.Attributes["path"] != null &&
Item.Attributes["path"].Value.Trim().Length > 0)
{
// Get the value of the path attribute
Path = Item.Attributes["path"].Value.Trim();
// Add leading and trailing "/" characters where needed
if (Path.Length > 1)
{
if (!Path.StartsWith("/"))
Path = "/" + Path;
if (SecurePathList == Settings.SecureDirectories
&& !Path.EndsWith("/"))
Path += "/";
}
// Check for an ignore attribute
if (Item.Attributes["ignore"] != null)
Ignore = (Item.Attributes[
"ignore"].Value.Trim().ToLower() == "true");
else
Ignore = false;
// Add the item to the collection
SecurePathList.Add(new SecureWebPageItem(Path, Ignore));
}
else
// Throw an exception for the missing Path attribute
throw new SecureWebPageSectionException(
"'path' attribute not found.", Item);
}
}
// Return the settings
return Settings;
}
This method parses the XML of the The SecureWebPageModule ClassThe public void Dispose()
{
// No resources were used.
}
The second method is the public void Init(HttpApplication Application)
{
// Add a reference to the private Application_BeginRequest
// handler to the application's BeginRequest event
Application.BeginRequest += (new EventHandler(
this.Application_BeginRequest));
}
Finally, the private void Application_BeginRequest(Object source, EventArgs e)
{
// Get the settings for the secureWebPages section
SecureWebPageSettings Settings =
(SecureWebPageSettings)ConfigurationSettings.GetConfig(
"secureWebPages");
if (Settings != null && Settings.Enabled)
{
// Cast the source as an HttpApplication instance
HttpApplication Application = (HttpApplication)source;
// Get the relative file path of the current
// request from the application root
string RelativeFilePath =
Application.Request.Url.AbsolutePath.Remove(
0,
Application.Request.ApplicationPath.Length).ToLower();
if (!RelativeFilePath.StartsWith("/"))
// Add a leading "/"
RelativeFilePath = "/" + RelativeFilePath;
// Intialize the flags
bool MakeSecure = false;
bool Ignore = false;
// Determine if there is a matching file path for
// the current request
int i = Settings.SecureFiles.IndexOf(RelativeFilePath);
if (i >= 0)
{
MakeSecure = true;
Ignore = Settings.SecureFiles[i].Ignore;
}
// Try to find a matching directory path, if no file was found
i = 0;
while (!MakeSecure && i < Settings.SecureDirectories.Count)
{
MakeSecure = RelativeFilePath.StartsWith(
Settings.SecureDirectories[i].Path.ToLower());
Ignore = Settings.SecureDirectories[i].Ignore;
i++;
}
// Test for the ignore flag
if (!Ignore)
{
// Request a secure/unsecure page as needed
if (MakeSecure)
SSLHelper.RequestSecurePage();
else
SSLHelper.RequestUnsecurePage();
}
}
}
The event handler retrieves the Adding the Module to an ApplicationIn order for a HTTP module to work with a web application, it must be added to the list of modules used. The machine.config file includes many modules for you. It's up to you to add any additional modules that you want to process your application(s). There are two ways you can add the module. The first option you have, is to add the module to an individual application. This requires that you edit the web.config file of the application. You will need to add a custom configuration section handler for the <?xml version="1.0" encoding="utf-8" ?>
<configuration>
...
<configSections>
...
<section
name="secureWebPages"
type="Hyper.Web.Security.SecureWebPageSectionHandler,
WebPageSecurity"
allowLocation="false" />
</configSections>
...
<system.web>
...
<httpModules>
...
<add
name="SecureWebPage"
type="Hyper.Web.Security.SecureWebPageModule,
WebPageSecurity" />
</httpModules>
...
</system.web>
...
</configuration>
Your second option is to add the module to all web applications. You will need to make similar modifications to the machine.config file. Editing the machine.config file should only be performed by a knowledgeable person with "Administrator" privileges. Always make a backup of your machine.config file before editing it. If you choose to add the module and configuration section handler to your machine.config file, you should sign the assembly with a strong name and register it in the Global Assembly Cache (GAC). The AssemblyInfo.cs file provided with the project source should have a line near the bottom, that is commented to prevent signing the assembly. To sign the assembly during a compile, un-comment this line. [assembly: AssemblyKeyFile(@"Key.snk")]
For more information on registering an assembly in the GAC, please refer to the .NET Framework documentation. Points of InterestThis module was desperately needed for a project I was working on earlier in the year. The web site contained nearly 100 pages and controls in 7 main directories. Some of the directories under the root contained directories as well. It was going to be a nightmare to secure certain areas and pages with absolute URLs. The | ||||||||||||||||||||