Configure, Store, And Read Secure Store Credentials Within SharePoint - Part Two

In the first part of the series we figured out how to configure and store the credentials within the Share Point Secure Store Service. There would be scenarios where we have to read the credentials from within the code to establish a connection with external systems via BCS. Though there are multiple ways to store credentials within Share Point, the most secure way is to use the native Secure Store Service.

Reading from Secure Store Service

Currently I have created a Secure Store Target Application ‘BCS’ where I have stored the credentials to connect to an external system. Now, say I want to read them from my code. Let’s see how we can do that.

For the demo I have created a Windows form application. Clicking on the Retrieve button should fetch me the Credentials.

What dll references should we add

  1. using Microsoft.SharePoint.Administration;  
  2. using Microsoft.Office.SecureStoreService.Server;  
  3. using Microsoft.BusinessData.Infrastructure.SecureStore;  
  4. using System.Security;  
  5. using System.Runtime.InteropServices;  
Note: You can get all other dlls except Microsoft.Office.SecureStoreService.Server is present in the Assemblies tab of Visual Studio. Secure Store Service dll is present under c:\Windows\Microsoft.NET\assembly\GAC_MSIL\Microsoft.Office.SecureStoreService.

Now let's jump into the code. 

On clickng  of the Retrieve Button I have placed the following code in the button click event handler.
  1. private void Retrieve_Click(object sender, EventArgs e)  
  2. {  
  3.     // Get the default Secure Store Service provider.  
  4.     ISecureStoreProvider provider = SecureStoreProviderFactory.Create();  
  5.     if (provider == null)  
  6.     {  
  7.         throw new InvalidOperationException("Unable to get an ISecureStoreProvider");  
  8.     }  
  9.     ISecureStoreServiceContextproviderContext = provider as ISecureStoreServiceContext;  
  10.     providerContext.Context = SPServiceContext.GetContext(GetCentralAdminSite());  
  11.     // Create the variables to hold the credentials.  
  12.     string userName = null;  
  13.     string password = null;  
  14.     string appId = "BCS";  
  15.     try  
  16.     {  
  17.         using(SecureStoreCredentialCollectioncreds = provider.GetCredentials(appId))  
  18.         {  
  19.             if (creds != null)  
  20.             {  
  21.                 foreach(SecureStoreCredential cred in creds)  
  22.                 {  
  23.                     if (cred == null)  
  24.                     {  
  25.                         continue;  
  26.                     }  
  27.                     switch (cred.CredentialType)  
  28.                     {  
  29.                         caseSecureStoreCredentialType.WindowsUserName: if (userName == null)  
  30.                             {  
  31.                                 userName = GetStringFromSecureString(cred.Credential);  
  32.                             }  
  33.                         break;  
  34.                         caseSecureStoreCredentialType.WindowsPassword: if (password == null)  
  35.                             {  
  36.                                 password = GetStringFromSecureString(cred.Credential);  
  37.                             }  
  38.                         break;  
  39.                     }  
  40.                 }  
  41.             }  
  42.         }  
  43.         if (userName == null || password == null)  
  44.         {  
  45.             throw new InvalidOperationException("Unable to get the credentials");  
  46.         }  
  47.         UserName.Text = userName;  
  48.         Password.Text = password;  
  49.     }  
  50.     catch (SecureStoreException ex)  
  51.     {  
  52.         throw;  
  53.     }  
  54. }  
  55. private static string GetStringFromSecureString(SecureStringsecStr)  
  56. {  
  57.     if (secStr == null)  
  58.     {  
  59.         return null;  
  60.     }  
  61.     IntPtrpPlainText = IntPtr.Zero;  
  62.     try  
  63.     {  
  64.         pPlainText = Marshal.SecureStringToBSTR(secStr);  
  65.         returnMarshal.PtrToStringBSTR(pPlainText);  
  66.     }  
  67.     finally  
  68.     {  
  69.         if (pPlainText != IntPtr.Zero)  
  70.         {  
  71.             Marshal.FreeBSTR(pPlainText);  
  72.         }  
  73.     }  
  74. }  
  75. public static SPSiteGetCentralAdminSite()  
  76. {  
  77.     SPAdministrationWebApplicationadminWebApp = SPAdministrationWebApplication.Local;  
  78.     if (adminWebApp == null)  
  79.     {  
  80.         throw new InvalidProgramException("Unable to get the admin web app");  
  81.     }  
  82.     SPSiteadminSite = null;  
  83.     Uri adminSiteUri = adminWebApp.GetResponseUri(SPUrlZone.Default);  
  84.     if (adminSiteUri != null)  
  85.     {  
  86.         adminSite = adminWebApp.Sites[adminSiteUri.AbsoluteUri];  
  87.     }  
  88.     else  
  89.     {  
  90.         throw new InvalidProgramException("Unable to get Central Admin Site.");  
  91.     }  
  92.     returnadminSite;  
  93. }  
The above code contains two main functions.
  1. GetCentralAdminSite – This function is used to get an instance of the Central Administration. It returs the SPSite of the CA site.

  2. GetStringFromSecureString – The credentials are encrypted using a passphrase which we create while Secure Store Service Application creation. The Encrypted password is decrypted and returned back as plain text.

Here the target application ID is ‘’BCS’ .The flow of the code is as below:

  • Get the Central Admin site object,
    1. providerContext.Context = SPServiceContext.GetContext(GetCentralAdminSite());  
  • Pass in the Target application id and get the Secure store credentials which is a key value pair.
    1. SecureStoreCredentialCollectioncreds = provider.GetCredentials(appId)  
  • Pass the Secure store id to the decryption function to get back plain text.
    1. userName = GetStringFromSecureString(cred.Credential);  
    2. password = GetStringFromSecureString(cred.Credential);  
    Final Output

    Click Secure

Reference