Geeks With Blogs

@mhuguet
  • mhuguet Saw a woman using a payphone at the airport. Wow, people still do that although rare! about 538 days ago

News


INETA Community Speakers Program


Mike Huguet
Mike Huguet

A smörgåsbord of technology

View my profile on LinkedIn





Mike Huguet I'm just talking out loud

This past week I was reminded of the “fun” in which hosting an application within SharePoint can present.  We are developing a custom application for our client in which some areas must reside within a SharePoint environment.  We did quite a bit of our development in this first iteration within a web application in order to pull things together and present the client with a working end-to-end “prototype.”  The architecture is composed of several layers all of which will be “in process” communications for the first release as depicted below.

image

As we started to move the designated presentation layer into SharePoint we ran into issues such as attempting to access resources using the NT Anonymous user.  We did not encounter this issue in a standalone ASP.NET application.  In order to work around this issue for the short term I turned off the security implementation, which was accessing AD, and changed the SQL Server database connection strings to use a SQL user instead of integrated security.  It is the intention of this design to use the the application pool identity to access the necessary resources in the environment.  This identity is an Active Directory account, which will be granted the appropriate permissions to the data stores and other local and network resources.  Why was this not found to be an issue while hosted within a standalone ASP.NET application on the same server, but breaks when moved into a SharePoint environment?  Well, the reason is that impersonation is set to true in the ASP.NET web.config file as well as the authentication mode being Windows.

<authentication mode="Windows" />
<identity impersonate="true" />

In the standalone application the authentication mode was windows, but impersonation was set to false.  This forces resources to be accessed using the identity of the site’s application pool.  Setting impersonate=true allows the resources to be accessed using the identity of the launching user.  Unfortunately, in a lot of organizations this behavior causes what is referred to as the “double hop” issue when the application attempts to access resources on another server or network resource.  Many organization don’t allow Kerberos trusts in their AD environment, which must be enabled in order to allow the identity to pass from server to server.  If you need more details on this, there are plenty of references online.  You can just search for “double hop kerberos.”  In this specific situation the user’s identity is passed through the browser from his client workstation to the server, which is one “hop.”  When attempting to access the database server or Active Directory because Kerberos was not fully enabled, Windows was unable to pass the identity to the other servers causing it to use the NT Anonymous user.  Of course this caused access denial errors in the application.

Unfortunately, for this application the answer was to find another manner in which to “force” accessing resources in the environment using the application pool’s identity since setting impersonate=false is not an option.  The SharePoint team so graciously provided us with the SPSecurity.RunWithElevatedPrivledges() method in order to accomplish this very need.  Wow, so does this mean that the lower depths of the system are now going to be forced to be aware of this need for the SharePoint API call?  Fortunately for us, we are using the MS Patterns and Practices Group’s Unity implementation throughout the Architecture for dependency injection and inversion of control.  This allowed us to swap out our Repository implementations for the database accesses with what I referred to as “SharePointRepositoryProxy” implementations.  The proxies are aggregation implementations that contain an injected instance of the Repository in which is necessary for data access.  The desired Repository implementation is injected using Unity’s constructor injection via the configuration in Web.config.

Here is the constructor for the base class’ implementation that accepts the injected parameter:

public BaseSharePointRepositoryProxy(IRepository<TEntity> repository)
{
WorkerRepository = repository;
IsRunningElevated = false;
}

Here is an example of a method implementation that switches the identity for accessing resources to that of the application pool:

public Appointment FindByAppointmentNumber(string appointmentNumber)
{
Appointment result = null;

if (IsRunningElevated)
{
result = WorkerRepository.FindByAppointmentNumber(appointmentNumber);
}
else
{
SPSecurity.RunWithElevatedPrivileges(delegate()
{
IsRunningElevated = true;
result = WorkerRepository.FindByAppointmentNumber(appointmentNumber);
});
IsRunningElevated = false;
}
return result;
}

You will notice that there is not much to this implementation.  It simply checks the base class’ property to determine if it requires making the call to SharePoint to switch the identity context and forwards the call to the worker Repository implementation.  This flag is important to our system as some methods may use other methods within the same repository and even reach into the base class to utilize common methods.  There is no need to call SPSecurity.RunWithElevatedPrivileges more than once.

The beauty of this is that when hosted within SharePoint all that we have to do is change the configuration for Unity to use the SharePointRepositoryProxy implementations and when not hosted within SharePoint use the normal IRepository implementation.  This allowed us to not have to change any existing framework code to accommodate SharePoint.

Based on what I have experienced and found in researching this appeared to be the most elegant solution.  I would love to hear if there is another way as it did take some time to create a proxy implementation for each IRepository interface.

Posted on Sunday, August 30, 2009 4:49 PM .NET General , Architecture , SharePoint | Back to top


Comments on this post: Accessing Resources/DB from an ASP.NET Application Hosted in SharePoint

No comments posted yet.
Your comment:
 (will show your gravatar)
 


Copyright © Mike Huguet | Powered by: GeeksWithBlogs.net | Join free