SharePoint 2010: Programatically Retrieve Credentials from the Secure Store Service

SharePoint 2010′s Secure Store Service provides a way to map credentials and delegate access to remote resources. You may already be familiar with the MOSS 2007 Single Sign-on Shared Service, which was the former equivalent. The Secure Store Service integrates seemlessly with Business Connectivity Services (BCS), but it also features an API that can be taken advantage of within custom development projects. This makes the service an attractive option for storing sensitive configuration data such as connection strings, Web service credentials, etc.

The Secure Store Service allows us to create Target Applications which house sets of credentials. The two main types are Individual and Group applications, Individual meaning credentials are mapped to individual users, and Group meaning all users share the same set of credentials.

While the raw API isn't very intuitive, its design was likely intentional (additional security by obfuscation). With a little marshalling help from our interop library friends, we are able to retrieve credentials (provided the appropriate permissions to the target application).

To begin, we need to reference a couple of assemblies.

Microsoft.BusinessData.dll

C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\ISAPI\Microsoft.BusinessData.dll

Microsoft.Office.SecureStoreService.dll

C:\Windows\assembly\GAC_MSIL\Microsoft.Office.SecureStoreService\14.0.0.0__71e9bce111e9429c\Microsoft.Office.SecureStoreService.dll

And now for the reason you came to this post … the code

using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Security; using Microsoft.BusinessData.Infrastructure.SecureStore; using Microsoft.Office.SecureStoreService.Server; using Microsoft.SharePoint;   namespace Trentacular.SharePoint.Util {     public static class SecureStoreUtils     {         public static Dictionary<string, string> GetCredentials(string applicationID)         {             var serviceContext = SPServiceContext.Current;             var secureStoreProvider = new SecureStoreProvider { Context = serviceContext };             var credentialMap = new Dictionary<string, string>();               using (var credentials = secureStoreProvider.GetCredentials(applicationID))             {                 var fields = secureStoreProvider.GetTargetApplicationFields(applicationID);                 for (var i = 0; i < fields.Count; i++)                 {                     var field = fields[i];                     var credential = credentials[i];                     var decryptedCredential = ToClrString(credential.Credential);                       credentialMap.Add(field.Name, decryptedCredential);                 }             }               return credentialMap;         }           public static string ToClrString(this SecureString secureString)         {             var ptr = Marshal.SecureStringToBSTR(secureString);               try             {                 return Marshal.PtrToStringBSTR(ptr);             }             finally             {                 Marshal.FreeBSTR(ptr);             }         }     } }