Friday 25 July 2008

Enable SSL for selected Pages in MOSS

An article on automatically switching between HTTP and HTTPS protocols without hard-coding absolute URLs

I came across a change request of my client who wants to enable SSL on selected pages in MOSS site collection. we all know that we can create SSL enabled web application from scratch. But here the requirement is unique and client requirement says he should be able to Enable SSL on pages of his choice. So it should be configurable and at same time we should be able to maintain session state across http and https. Amazingly MOSS has that ability to support session state when switching across HTTP and HTTPS. I followed the steps below and was able to achieve result
1) Wrote a custom HTTP handler which redirects http to https for selected pages.

2) The page list is read from web.config file.
****** Source code for HTTP handler************************
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Security;
using System.Diagnostics;

namespace muki.ForceSSL
{
public class ForceSSL : System.Web.IHttpModule
{
#region IHttpModule Members

public void Dispose()
{
throw new NotImplementedException();
}

public void Init(System.Web.HttpApplication context)
{
context.BeginRequest += new EventHandler(context_BeginRequest);

}

#endregion

void context_BeginRequest(object sender, EventArgs e)
{
RedirectSSL(System.Web.HttpContext.Current.Request.Url.PathAndQuery);
}
public void RedirectSSL(string pageURL)
{
//check for the current page exists in the group of pages requiring SSL
//if page is found in ssl group then redirect using https:// otherwise redirect with http://
bool found = false;
string sslPages = System.Configuration.ConfigurationSettings.AppSettings["SSLPages"];
char[] separator;
separator = new char[] { ',' };
string[] pages;
pages = sslPages.Split(separator);
for (int i = 0; i < pages.Length; i++)
{

if( pageURL.ToLower().Contains(pages[i].ToLower()))
{
found = true;
break;
}
}
if (found)
{
if (System.Web.HttpContext.Current.Request.Url.Scheme.ToString() == "http")
{
string sURL = System.Web.HttpContext.Current.Request.Url.ToString();
sURL = sURL.Replace("http://", "https://");
System.Web.HttpContext.Current.Response.Redirect(sURL);

}
}
else
{
if (System.Web.HttpContext.Current.Request.Url.Scheme.ToString() == "https")
{
string sURL = System.Web.HttpContext.Current.Request.Url.ToString();
sURL = sURL.Replace("https://", "http://");
System.Web.HttpContext.Current.Response.Redirect(sURL);
}
}

}
}



}
**********************************Source code for Http handler ends**************
4) Sign this assembly and GAC it.

5) Add this line <httpmodules> section and see that this line is first among all
<add name="ForceSSL" type="muki.ForceSSL.ForceSSL, ForceSSL,Version=1.0.0.0, Culture=neutral,PublicKeyToken=xxxxxxxx" />
Add key in Appsettings of web.config file like this.
<add key="SSLPages" value="/SitesWithSSL/Pages/SSL1.html,/subsite/Pages/SSL1.aspx" />
we can add as many pages we need for this. All these pages would be SSL enabled.

6)Now come to IIS-->WebApplication which needs SSL enabling for selected pages

7)Navigate to Properties--Directory Settings--Secure Communications--Server Certificate-->Assign the existing certificate.
More Details on SSL enabling

8)Assign port 443 for SSL ( we can choose port of our choice, but we should be aware that 443, 80 doesnt require ports to be mentioned in URL, otherwise we have to tweak our code settings to read through those ports)

9)Please be sure that in Directory settings-->SecureCommunications-->Edit-->Require Secure Channel is NOT SELECTED.

10)Now come back to Central Administration-->Operations-->Alternate Access Mappings

11)Add the new URL via internal URL's link.
https://servername//.

12)Perform IISReset-->Now Browse Application..
we can see our selected pages(as specified in web.config) are over SSL mode and the rest are under normal HTTP.

Cheers! we are done

26 comments:

Anonymous said...

Hi there,

Great post, am facing exactly the same scenario. I am just making the login page of my application to come under SSL. But even after doing all the steps as explained by you, when I try accessing my application, it shows IE cannot display the page. Even if in the url I myself type https:// and then the url, it also doesn't seem to work. Any ideas what might be wrong. I have SSL certificate etc, all in place.

muki said...

hi,

Is the problem solved? please let me know.

Anonymous said...

Hi Muki,
It is a great post. We faced the same issue and we followed your steps and ultimately won in the game
Ton of Thanks,
Geogy

Anonymous said...

Dear Muki,

1) Do we need to extend the sharepoint application i.e one with http and another with https://.

2) While configuring the sharepoint webapplication should we make it SSL or non-SSL

Anonymous said...

Hi,

No need to extend the Application with Http or HTTPS or no need of configuring it with HTTP or HTTPS
You can use existing sharepoint application itself.
Refer the steps listed out.
1. Create a webapplication in MOSS.( No need to configure any SSL at this level)
2. Create a site collection underneath that webapplication createdand Create some pages.
3. Go to IIS-->Open this webapplication-->Add SSL certificate.
4. Deploy the handler and test.

Anonymous said...

Hi there I tried implementing your code and came across 2 problems.

1 it doesn't seem to access the value from the web.config file for the ssl pages and 2 it doesn't switch from https to http but works fine from http to https.

Any help would be greatly appreciated

muki said...

Did you create a node in the web.config file as mentioned

<add key="SSLPages" value="/SitesWithSSL/Pages/SSL1.html,/subsite/Pages/SSL1.aspx" />

And second issue should be solved automatically.

Anonymous said...

Hi yes I did it seems when the page is https it returns a null value from the web config because it cannot access it. Did you come across this? Is there some setting to be able to access the web.config with ssl?

muki said...

I never encountered this. I hope you havent created another application for http and https. Same application should be used. But as per comment it appears that it is able to get result when its switching from http to https and when switching back its unable to do.
So I understand that you are using two different applications. if it is the case we cannot maintain the session state across different apps.so its not required to have different application.

Anonymous said...

We are using the same application but the web.config can't be accesed. Other web parts that get values from the web.config also break when viewed as https but work fine as http (exact same page). Any ideas? This is driving me crazy!

Anonymous said...

We got it sorted! There were other web apps on the box set up to use ssl so we cleared them off and it started working. Guess there was some sort of conflict.

Very frustrating but at least it's working now. Thanks for your help!!

Anonymous said...

great article.Very infromative.
I have a problem with my sharepoint portal.I created a page and made that to be https.
Even after doing all the steps as explained by you, when I try accessing my application, it shows http page only. Any ideas what might be wrong.

muki said...

hi there,

Check your web.config file and also did you enter the SSL pages and confirm those pages are accessible to normal users( THey should be published).
Still if you are unable to get it,please let me know your implementation steps.

cheers
muki

Anonymous said...

Hi,
thanx a lot for ur quick response.
My sharepoint portal url is http://servername/SampleSite/Pages/default.aspx.
In that i added SampleSSL.aspx page.I want that page to be https.
This is what i added in webconfig.
In httpModules
add name="HttpHandler" type="HttpHandler.MyHttpHandler,HttpHandler,Version=1.0.0.0,Culture=neutral,PublicKeyToken=xxxx"
And in appsettings
add key="SSLPages" value="/SampleSite/Pages/SampleSSL.aspx"

Im not sure if Ive done something wrong here.

Anonymous said...

Hi,

I have created portal with a port number 200 and SSL port number 443.

In the lasdt step u have mentioned like Add the new URL via internal URL's link. https://servername//.
So in my case do i need to add https://servername:200/.
it is not working. And i tried adding https://servername// . Then all the pages are displayed as https.Please help me out to solve this.

Anonymous said...

Hi,

Now you are on the correct phase.
Now edit your code which is doing a redirect. include Port number in your Code when redirecting them to normal mode from HTTPS.
In general if your port is 80 or 443 then there is no need to mention them in your code.
let me know how it works

Anonymous said...

Hi Muki,

Im able to switch from https to http. But when i try other way round, the page is still coming in http...

David Solsona Font said...

Thanks for your help, it save my time and our big problem with https. Due to a problem with IE8 (always requesting if you want to open page with non secure items) I have update the code to convert only .aspx pages and leave the rest of content with same protocol.
Thanks a lot,
David

Anonymous said...

Hi there,
I have implemented your solution successfully. But the think is that once I use alternate access mapping, the http is not working as right:

It is showing the error: An error occurred during the processing of /_catalogs/masterpage/VECCIHomeSplashPanel.aspx. Code blocks are not allowed in this file

I already allowed code block in web.config.

Any suggestions?

Anonymous said...

Hi there,

I think there is no issue with http handler or Alternate access Mappings..As per the page you mentioned it appears to be layout page.

Did you add the web.config entry for that page
<PageParserPaths>
<PageParserPath VirtualPath="/_catalogs/masterpage/VECCIHomeSplashPanel.aspx" CompilationMode="Always" AllowServerSideScript="true" />
</PageParserPaths>

Perform IISRESET after modifying the config file
Try this, it may help.

Unknown said...

Hi there,

I have a virtual directory attached to the web site. I need to secure one page from there. But when I used this approach it is not picking the pages inside the virtual directory.

This only for the pages inside virtual directory. Appreciate your thoughts on this.

thanks

supun

Anonymous said...

@Supun,

is your problem solved? Are you specifying the full path when accessing the pages in virtual directory? Where is that virtual directory located, is it in same webapp where you have implemented this SSL? How you are accessing your Virtual Directory page?

Anonymous said...

Nice dispatch and this post helped me alot in my college assignement. Thank you on your information.

Cheap SSL Certificates said...

Hope you havent created a new application for http and https. Same application to use. But according to comments seems to be able to get the result when the change from http to https and when you switch back your unable to do. Great information you have suggest here.

Anonymous said...

I have followed this and it worked great ,the page http://****/_layouts/settings.aspx where i applied the ssl requires credentials to access it.

After hitting the above URL it redirects me to HTTPS URL of that same page, where i have to enter the credentials . after entering the credentials the page gets refreshed but still does not get logged in

This behaviour happens only in IE7 and safari ,it works well in other browsers

any help would be greatly appreciated

going into that however when using safari i am not able to login using https url

Anonymous said...

Please ignore the last line of my above comment going into that however when using safari i am not able to login using https url