Thursday, November 6, 2008

Using SiteMinder authentication in Sharepoint

Introduction
Many enterprise IT environments use Netegrity SiteMinder (hereafter called SiteMinder) to secure Web applications and servers. When customers decide to move to MS SharePoint 2007 (MOSS), they want to continue to use SiteMinder for their existing Web environment, and also as the authentication mechanism for their portal.
This article is an example of the implementation of the solution that allows using the SiteMinder authentication with WSS 3.0.
The key technical points of the solution:
1. SiteMinder authentication.
2. FBA (Form Based Authentications) for SharePoint applications.
3. Custom login form.
4. Custom membership and role providers.

SiteMinder authentication

The SiteMinder authentication is used for single sign on (SSO) functionality. Once SiteMinder authenticates a user it adds a special HTTP header with the user name to each HTTP request. SiteMinder can also create an authentication cookie that can be used if you want client software integration, for example, if you want to modify a document from a document library, using MS Word.
Since the SiteMinder authenticates users, the SharePoint authentication can be, and should be bypassed, we trust that the user is already authenticated and her name is contained in the HTTP header. The custom login form pulls the UserID from the HTTP header, creates the authentication token and redirects the request to the destination page. The trick is to make the SharePoint framework to authorize (or deny) the authenticated user correctly. To resolve users and role names the SharePoint framework has to use custom membership and role providers.
FBA (Form Based Authentications) and custom login form.
Since we are going to use the custom authentication mechanism (not Windows authentication) we have to use the Form Based Authentication. Our form shouldn’t have any UI, and user shouldn’t even be aware that the form is called.
The FBA has to be set up on the SharePoint Central Administration website. After opening the site go to: Application management->application security->authentication providers
At this point make sure that you are changing the right SharePoint application, the application URL is displayed at the upper-right corner of the page.
When you see the authentication type for your application (it’s windows by default) click “Default” and you will be navigated to the “Edit authentication” page.
On this page you can set up the Form Based authentication and the membership and role providers.
If you want to be able to edit documents from document libraries using MS Office software, don’t forget to click the “client software integration” radio-button
After you set up the FBA authentication for a SharePoint application, the central administration web site changes the web.config file of the SharePoint application. It sets up the authentication to “Forms” and loginURL to _layouts\logon.aspx. In the modified web.config file of the SharePoint application you will see something like this:

<authentication mode="Forms" > <forms loginUrl="_layouts\login.aspx"/> </authentication>

This setting will cause any unauthenticated request to be redirected to the SharePoint default login.aspx page and the user will be prompted to type her User Name and Password. It’s not what we want, our purpose is to let the user, authenticated by the SiteMinder, bypass any additional authentication. The login form shouldn’t have any UI. Replace the loginURL attribute with the name of the custom web page (in this example the name of the page is SiteMInder_Login.aspx).
Figure 2 SiteMinder_Login.aspx.cs
public partial class SiteMinder_Login : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string strUserName = GetCurrentUserLoginID(Request);
FormsAuthentication.RedirectFromLoginPage(strUserName, true);
}
public static string GetCurrentUserLoginID(System.Web.HttpRequest Request)
{

string strHeaderName = System.Web.Configuration.WebConfigurationManager.AppSettings["UserIdHeaderName"];
return GetSMAttribute(strHeaderName, Request);

}

public static string GetSMAttribute(string AttrName, System.Web.HttpRequest Request)
{
string AllAttrs = Request.ServerVariables["ALL_HTTP"];
int Location = AllAttrs.IndexOf(AttrName);
string bigResult = AllAttrs.Substring(Location + AttrName.Length + 1);
int N_Location = bigResult.IndexOf('\n');
string strResult = bigResult.Substring(0, (N_Location - 1));

return strResult;
}
}
The GetSMAttribute method gets the HTTP header with the user name. For some reason Request.Headers[AttrName] didn’t work for me, it just wouldn’t find the header, so I had to get “ALL_HTTP” server variable string and then parse it.
Another tip: looks like you don’t get the SiteMinder headers if the Session is disabled (it’s disabled by default on SharePoint applications), so you will have to enable the Session in the application web.config file.
After the login page pulls the user name from the HTTP header it redirects the user to the requested page and creates the form authentication token. It also creates the persistent cookie (the second parameter in the method is true). You need the persistent cookie if you decided to use “client software integration” feature.

Custom membership and role providers
Since we are not using Windows authentication we need to define membership and role providers for the SharePoint application and Central Administration site.
After the SiteMinder authenticates a user, the SharePoint framework has to authorize the user. When SharePoint site authorizes users, it uses the list of users and roles assigned to the site. To assign users and roles to the site in SharePoint 2007 you use the Central Administration site (to assign site collection admins) or Site Settings (to assign users and groups). In both cases the SharePoint framework uses membership and role providers. The framework calls appropriate methods of the providers to search for users and roles. Providers make calls to data sources that contain users, groups and relationship information between users and groups.
By the way, SharePoint stores users and groups assigned to sites in the Contents database in the form: ProviderName:UserName.
If your SiteMinder agent authenticates users against a specific AD domain you can use LDAP membership and role providers that will talk to the same AD domain.
In some more complex cases one of possible solutions would be copying the users and roles information in a SQL server database and use providers that talk to this database.
Figure 3 The HTTP request sequence diagram






See my blog about custom membership and role providers for SharePoint 2007.

Additional information
There are blogs on the Internet about using the SiteMinder headers to bypass the SharePoint authentication.
http://www.huffs.us/blog/2007/04/siteminder-and-sharepoint-2007.html
http://blogs.msdn.com/danielma/archive/2005/11/16/493519.aspx
In both cases the SiteMinder talks to one AD domain, and because of that, it was not necessary to develop custom providers. The authors of the articles use LDAP membership and role providers that talk to the same data source (AD domain) as the ‘SiteMinder’.
There is another trick both articles are using, instead of changing login.aspx they create HTTP modules that intercept all requests, and create generic principal object using the user name from the SiteMinder header. In this case login.aspx is never called.
It’s not absolutely obvious, and it’s not covered by the article but looks like in both cases the role provider is not used, so the roles are not used for the SharePoint applications.

9 comments:

Kit said...

We have implemented wss 3 and siteminder integration and it works fine. The one issue that I have noticed (this is a big deal) is that when the user click on a document to view it, instead of seeing the document content, the user sees the siteminder login page. Any ideas how to fix this?

Vladimir Gedgafov said...

In the set up authentication provider page (SP central administration) you need to set up "Enable Client Integration" (it should be Yes.

Anonymous said...

Why do we need to setup a connection between sharepoint and LDAP?
Whenever user accesses the site, will sharepoint makes a new connection to LDAP to get the user info or will it take from internal db.

Anonymous said...

Iam unable to configure Siteminder with WSS site.
In my case Siteminder is installed in one of our front end web server.
I have added a new virtual directory (SampleSite) under siteminder website by giving sharepoint site folder (wwwroot\wss\virtualdirectories) as a content path.
Now Iam trying to access the site by siteminder url https://siteminderurl.com/SampleSite and it is giving resource not found error.

Anonymous said...

Very Good Article Vladimir Gedgafov... perhaps it was really usefull for the Siteminder guys.. So far i work for siteminder in CA as Senior Administrator

Antti Ropponen said...

Is it possible to authenticate users with SiteMinder using Integrated Windows Authentication and just pass forward the authentication data to MOSS?

Vladimir Gedgafov said...

If your SiteMinder UserID exactly match Windows UserIDs you can use Windows API to impersonate Windows user. In this case you can use Windows authentication in MOSS.

Rosa said...

Hello,
CA has a custom SiteMinder Agent for SharePoint. I wonder if it provides any additional benefit besides the integration that can be achived via the code that Vladimir described.
Also our SiteMinder is configured against SunOne LDAP and not against Active Directories, so I wonder how much difference does it make? Thank you in advance for any comment on this.

Senthamil said...

Hi Vladimir,
I am interested in the comment date :July 29, 2009 5:51 AM.

In my case the Site Minder id is same as the windows id. Can you plese let me know how to impersonate the user id? Still do we need to create the FBA and use the windows authentication and impersonate the user?

Please provide the steps to do it. It will be very helpful to me.

Followers