Monday, November 28, 2011

Creating a Secure Store Target application with access for all users

I am currently working on a SharePoint application which access users Exchange calendars via web services. In order to access the calendars we need to provide credentials and we use a service account which has access to all calendars.

Instead of storing the logon information of the service account in a list or web.config we want to store this in Secure Store which is ideal for storing credentials (big surprise there). We also want to create the Secure Store target application in code with an installer and not using Central Admin.

This is all very straight forward. First we get a reference to the Secure Store with the following code

SPServiceContext context = SPServiceContext.GetContext(SPServiceApplicationProxyGroup.Default, SPSiteSubscriptionIdentifier.Default);
SecureStoreServiceProxy ssp = new SecureStoreServiceProxy();
ISecureStore iss = ssp.GetSecureStore(context);

And in order to create the Target Application we use the CreateApplication method of the ISecureStore object.

void CreateApplication(TargetApplication application, IList<TargetApplicationField> applicationFields, TargetApplicationClaims applicationClaims);

The issue comes when you want to create the claims going in as the third parameter. In our case we want all users to use the same credentials in the form of all authenticated users and I’ve create a “group” type target application. For “group” type target applications we have to set the administrator and member claims on the TargetApplicationClaims object.

But what should we pass in? If you use the wizard in SharePoint admin to set the credentials, the user picker control will do the conversion for us from whatever user or group we enter. When programming this ourselves it’s a different matter.

My trusty old friend Reflector helped me out and I found the perfect claims provider for my use.

Microsoft.SharePoint.Administration.Claims.SPAllUserClaimProvider

This class has a static method named “CreateAuthenticatedUserClaim” which return a claim for all authenticated users.  (Try Google the method name and see how much help you get).

The final code looks something like this:

TargetApplication app = new TargetApplication("appid", "friendlyname", "admin@email.com", 0, TargetApplicationType.Group, null);
List<TargetApplicationField> fields = <the fields in the target app>;
string administator = "DOMAIN\\adminuser";
var adminWindowsClaim = SPActiveDirectoryClaimProvider.CreateUserClaim(administator);
SecureStoreServiceClaim adminSecureClaim = new SecureStoreServiceClaim(adminWindowsClaim);

SPClaim groupWindowsClaim = SPAllUserClaimProvider.CreateAuthenticatedUserClaim(true);
SecureStoreServiceClaim groupSecureClaim = new SecureStoreServiceClaim(groupWindowsClaim);

TargetApplicationClaims apc = new TargetApplicationClaims(new List<SecureStoreServiceClaim> { adminSecureClaim }, new List<SecureStoreServiceClaim> { groupSecureClaim }, new List<SecureStoreServiceClaim>());
iss.CreateApplication(app, fields, apc);