locked
How to Programatically SetCredentials for Secure Store Service Application in Sharepoint 2010 using VS 2010 RRS feed

  • Question

  • I have to setup Credentials for Secure Store Service application programatically. To get Stored Credentials I have following code and its working fine.

    using (SPSite site = new SPSite("http://vtlssp2010Dev"))

    //using (SPSite site = new SPSite("http://" +
    System.Environment.MachineName + "/sites/Site_Name"))d
    {
    Console.WriteLine(site.RootWeb.CurrentUser.Name);
    SPServiceContext context =
    SPServiceContext.GetContext(site);
    prov.Context = context;

    try
    {

    SecureStoreCredentialCollection cc =
    prov.GetCredentials(appID);


    foreach (SecureStoreCredential c in cc)
    {
    IntPtr ptr =
    System.Runtime.InteropServices.Marshal.SecureStringToBSTR(c.Credential);
    string sDecrypString =
    System.Runtime.InteropServices.Marshal.PtrToStringUni(ptr);
    Console.WriteLine(sDecrypString);
    }
    }
    catch (Exception ex)
    {
    Console.WriteLine("Unable to get credentials for
    application " + appID);
    Console.WriteLine(ex.Message);
    }
    Console.ReadLine();
    }
    }

    All I want is to programmatically do set credentials like explained in this example on msdn. http://msdn.microsoft.com/en-us/library/ff798456.aspx

    Please help.

    Shamshad Ali

     

    Tuesday, July 20, 2010 1:57 PM

Answers

  • When you create a new Target Application you can set the Target Application Type. Some of these options are for individuals types. Individual types require an owner to be set for the credentials and that is what the SPClaim object is for. Claim can be set for a group or any other type of account, the SPOriginalIssueerType is for the claims platform type.

    Like I said before it appears you cannot explicitly delete credentials, you can only overwrite them, and verification cannot be done because it appears the user name and password cannot be read, this is why they do not appear again in the UI.


    certdev.com
    Monday, July 26, 2010 2:57 PM
  • Hi Shamshad, upon further research you need to use the SecureStoreServiceProxy to get the ISecureStore interface. Once you have this you can set credentials, delete credentials and also verify the credentials. I listed the code below. It has a ReadSecureString method and VerifyStoredCredentials method so you can check that the credentials are set. The strange thing, is the SharePoint UI continues to use the obsolete code as of RTM.

     internal static SecureString MakeSecureString(string str)
        {
          if (str == null)
          {
            return null;
          }
          SecureString str2 = new SecureString();
          char[] chArray = str.ToCharArray();
          for (int i = 0; i < chArray.Length; i++)
          {
            str2.AppendChar(chArray[i]);
            chArray[i] = '0';
          }
          return str2;
        }
    
        internal static string ReadSecureString(SecureString sstrIn)
        {
          if (sstrIn == null)
          {
            return null;
          }
          IntPtr ptr = Marshal.SecureStringToBSTR(sstrIn);
          string str = Marshal.PtrToStringBSTR(ptr);
          Marshal.ZeroFreeBSTR(ptr);
          return str;
        }
    
    
    
        public static void SetCredentials(string userName, string userPassword, string targetApplicationID)
        {
    
          IList<ISecureStoreCredential> creds = new List<ISecureStoreCredential>(2);
          creds.Add(new SecureStoreCredential(MakeSecureString(userName), SecureStoreCredentialType.WindowsUserName));
          creds.Add(new SecureStoreCredential(MakeSecureString(userPassword), SecureStoreCredentialType.WindowsPassword));
    
          using (SecureStoreCredentialCollection credentials = new SecureStoreCredentialCollection(creds))
          {
           
              SPClaim claim = SPClaimProviderManager.CreateUserClaim("basesmc2008\\steve.curran", SPOriginalIssuerType.Windows);
              SecureStoreServiceClaim ssClaim = new SecureStoreServiceClaim(claim);
             
              SPServiceContext context =
              SPServiceContext.GetContext(SPServiceApplicationProxyGroup.Default, SPSiteSubscriptionIdentifier.Default);
    
              SecureStoreServiceProxy ssp = new SecureStoreServiceProxy();
              ISecureStore iss = ssp.GetSecureStore(context);
              iss.SetUserCredentials(targetApplicationID, ssClaim, credentials);
    
              //if the target application is using group type credentials then call this.
              //iss.SetGroupCredentials(targetApplicationID, credentials);
    
          }
        }
    
        public static SecureStoreCredentialCollection GetCredentials(string targetApplicationID)
        {
          SecureStoreCredentialCollection credentials = null;
          
          SPServiceContext context =
          SPServiceContext.GetContext(SPServiceApplicationProxyGroup.Default, SPSiteSubscriptionIdentifier.Default);
    
          SecureStoreServiceProxy ssp = new SecureStoreServiceProxy();
          ISecureStore iss = ssp.GetSecureStore(context);
          credentials = iss.GetCredentials(targetApplicationID);
          return credentials;
     
        }
    
        public static List<string> VerifyStoredCredentials(SecureStoreCredentialCollection credentials)
        {
          List<string> vcreds = new List<string>();
    
          foreach (SecureStoreCredential ssc in credentials)
          {
            vcreds.Add(ReadSecureString(ssc.Credential));
          
          }
    
          return vcreds;
        
        }
    
        public static void DeleteSecureStoreCredentials(string targetApplicationID)
        {
          SPServiceContext context =
            SPServiceContext.GetContext(SPServiceApplicationProxyGroup.Default, SPSiteSubscriptionIdentifier.Default);
    
          SecureStoreServiceProxy ssp = new SecureStoreServiceProxy();
          ISecureStore iss = ssp.GetSecureStore(context);
          iss.DeleteCredentials(targetApplicationID);
        
        }
    

    certdev.com
    Wednesday, July 28, 2010 6:29 PM

All replies

  • Hi Shamshad,

    Below is code that sets a target application's credentials. You can only replace credentials, you cannot add credentials. The API states the code is now obsolete even though the SharePoint UI continues to use it. I hope this helps you understand how to do this. Its a good starting point.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Security;
    using Microsoft.SharePoint;
    using Microsoft.SharePoint.Administration;
    using Microsoft.SharePoint.Administration.Claims;
    using Microsoft.Office.SecureStoreService.Server;
    using Microsoft.BusinessData.Infrastructure.SecureStore;
    
    namespace MasterHelper2010
    {
      public static class SecureStoreManagement
      {
    
    
        internal static SecureString MakeSecureString(string str)
        {
          if (str == null)
          {
            return null;
          }
          SecureString str2 = new SecureString();
          char[] chArray = str.ToCharArray();
          for (int i = 0; i < chArray.Length; i++)
          {
            str2.AppendChar(chArray[i]);
            chArray[i] = '0';
          }
          return str2;
        }
    
    
        internal static SecureStoreServiceApplicationProxy GetSecureStoreProxy()
        {
    
          SPServiceContext context =
              SPServiceContext.GetContext(SPServiceApplicationProxyGroup.Default, SPSiteSubscriptionIdentifier.Default);
    
          SecureStoreServiceApplicationProxy sssProxy = context.
            GetDefaultProxy(typeof(SecureStoreServiceApplicationProxy)) as SecureStoreServiceApplicationProxy;
    
    
          return sssProxy;
        
        }
    
        public static void SetCredentials(string userName, string userPassword, string targetApplicationID)
        {
    
          IList<ISecureStoreCredential> creds = new List<ISecureStoreCredential>(2);
          creds.Add(new SecureStoreCredential(MakeSecureString(userName), SecureStoreCredentialType.WindowsUserName));
          creds.Add(new SecureStoreCredential(MakeSecureString(userPassword), SecureStoreCredentialType.WindowsPassword));
    
          using (SecureStoreCredentialCollection credentials = new SecureStoreCredentialCollection(creds))
          {
            SecureStoreServiceApplicationProxy sssProxy = GetSecureStoreProxy();
            if (sssProxy != null)
            {
              SPClaim claim = SPClaimProviderManager.CreateUserClaim("basesmc2008\\steve.curran", SPOriginalIssuerType.Windows);
              SecureStoreServiceClaim ssClaim = new SecureStoreServiceClaim(claim);
              sssProxy.SetUserCredentials(targetApplicationID,ssClaim,credentials);
    
              //if the target application is using group type credentials then call this.
              //sssProxy.SetGroupCredentials(targetApplicationID, credentials);
            }
          }
    
          
    
        
        }
    
      }
    }
    

     


    certdev.com
    Friday, July 23, 2010 8:03 PM
  • The code sample is working But it does not practically set the credentials, wherein if i setup credentials via UI it does work. I have one question from above line:

     SPClaim claim = SPClaimProviderManager.CreateUserClaim("basesmc2008\\steve.curran", SPOriginalIssuerType.Windows);
    
    

    what is the SPOriginalIssuerType context? should i use the site admin or the user whom credentials are being setup under the same user account? Like you have explicitly mentioned your credentials as "basesmc2008\\steve.curran"

    There would be problem when delivering this code to client we must need this context ....

    Also i would like to verify how much of the Target application Id has stored credentials into database? How do i verify and delete existing credentials? To test it I have to manually delete the application ID again and again to setup and then Get Credentials.

    Please help me with code sample. Thanks again for your support.

     

    Shamshad Ali.

    • Edited by Shamshad Ali Monday, July 26, 2010 1:56 PM verified the sample code it does not give error but it wont practically set credentials againt given Target appID
    Monday, July 26, 2010 1:07 PM
  • When you create a new Target Application you can set the Target Application Type. Some of these options are for individuals types. Individual types require an owner to be set for the credentials and that is what the SPClaim object is for. Claim can be set for a group or any other type of account, the SPOriginalIssueerType is for the claims platform type.

    Like I said before it appears you cannot explicitly delete credentials, you can only overwrite them, and verification cannot be done because it appears the user name and password cannot be read, this is why they do not appear again in the UI.


    certdev.com
    Monday, July 26, 2010 2:57 PM
  • OK, its fine, I got it. with you given sample code I am getting a warning below:

    'Microsoft.Office.SecureStoreService.Server.SecureStoreServiceApplicationProxy.SetUserCredentials(string, Microsoft.Office.SecureStoreService.Server.SecureStoreServiceClaim, Microsoft.BusinessData.Infrastructure.SecureStore.SecureStoreCredentialCollection)' is obsolete: 'Use the ISecureStore interface to call into the SSS OM'

    Could you please guide me in this with change in your code sample earlier?

     

    Shamshad Ali. 

    Wednesday, July 28, 2010 10:43 AM
  • Hi Shamshad, upon further research you need to use the SecureStoreServiceProxy to get the ISecureStore interface. Once you have this you can set credentials, delete credentials and also verify the credentials. I listed the code below. It has a ReadSecureString method and VerifyStoredCredentials method so you can check that the credentials are set. The strange thing, is the SharePoint UI continues to use the obsolete code as of RTM.

     internal static SecureString MakeSecureString(string str)
        {
          if (str == null)
          {
            return null;
          }
          SecureString str2 = new SecureString();
          char[] chArray = str.ToCharArray();
          for (int i = 0; i < chArray.Length; i++)
          {
            str2.AppendChar(chArray[i]);
            chArray[i] = '0';
          }
          return str2;
        }
    
        internal static string ReadSecureString(SecureString sstrIn)
        {
          if (sstrIn == null)
          {
            return null;
          }
          IntPtr ptr = Marshal.SecureStringToBSTR(sstrIn);
          string str = Marshal.PtrToStringBSTR(ptr);
          Marshal.ZeroFreeBSTR(ptr);
          return str;
        }
    
    
    
        public static void SetCredentials(string userName, string userPassword, string targetApplicationID)
        {
    
          IList<ISecureStoreCredential> creds = new List<ISecureStoreCredential>(2);
          creds.Add(new SecureStoreCredential(MakeSecureString(userName), SecureStoreCredentialType.WindowsUserName));
          creds.Add(new SecureStoreCredential(MakeSecureString(userPassword), SecureStoreCredentialType.WindowsPassword));
    
          using (SecureStoreCredentialCollection credentials = new SecureStoreCredentialCollection(creds))
          {
           
              SPClaim claim = SPClaimProviderManager.CreateUserClaim("basesmc2008\\steve.curran", SPOriginalIssuerType.Windows);
              SecureStoreServiceClaim ssClaim = new SecureStoreServiceClaim(claim);
             
              SPServiceContext context =
              SPServiceContext.GetContext(SPServiceApplicationProxyGroup.Default, SPSiteSubscriptionIdentifier.Default);
    
              SecureStoreServiceProxy ssp = new SecureStoreServiceProxy();
              ISecureStore iss = ssp.GetSecureStore(context);
              iss.SetUserCredentials(targetApplicationID, ssClaim, credentials);
    
              //if the target application is using group type credentials then call this.
              //iss.SetGroupCredentials(targetApplicationID, credentials);
    
          }
        }
    
        public static SecureStoreCredentialCollection GetCredentials(string targetApplicationID)
        {
          SecureStoreCredentialCollection credentials = null;
          
          SPServiceContext context =
          SPServiceContext.GetContext(SPServiceApplicationProxyGroup.Default, SPSiteSubscriptionIdentifier.Default);
    
          SecureStoreServiceProxy ssp = new SecureStoreServiceProxy();
          ISecureStore iss = ssp.GetSecureStore(context);
          credentials = iss.GetCredentials(targetApplicationID);
          return credentials;
     
        }
    
        public static List<string> VerifyStoredCredentials(SecureStoreCredentialCollection credentials)
        {
          List<string> vcreds = new List<string>();
    
          foreach (SecureStoreCredential ssc in credentials)
          {
            vcreds.Add(ReadSecureString(ssc.Credential));
          
          }
    
          return vcreds;
        
        }
    
        public static void DeleteSecureStoreCredentials(string targetApplicationID)
        {
          SPServiceContext context =
            SPServiceContext.GetContext(SPServiceApplicationProxyGroup.Default, SPSiteSubscriptionIdentifier.Default);
    
          SecureStoreServiceProxy ssp = new SecureStoreServiceProxy();
          ISecureStore iss = ssp.GetSecureStore(context);
          iss.DeleteCredentials(targetApplicationID);
        
        }
    

    certdev.com
    Wednesday, July 28, 2010 6:29 PM
  • Thanks alot for such great support.

    The 2 methods above GetCredentials and DeleteSecureStoreCredentials are taking only targetAppId parameter, which I suppose to be with UserName and Pwd as mentioned in your code while setting the credentials in SetCredentials(string userName, string userPassword, string targetApplicationID) method.

    Further the method VerifyStoredCredentials seems to run in the same user context which is logged into sharepoint site. Is that correct? or it returns a list of all users credentials for the given targetAppId? Unfortunately I have not yet tested this method yet, did not get chance to test it.

    Secondly, is there any way to delete and Get only the specific UserName for specific targetAppId? or it is by default get/delete (run in user context) in the existing windows user context which is logged in to Sharepoint site?

    Hope you got my point and clear the confusion I have.

     

    Shamshad Ali.

    Friday, July 30, 2010 2:33 PM
  • Hi,

    Thanks, the above code is very supportive,

    SecureStoreServiceProxy ssp = new SecureStoreServiceProxy();
    ISecureStore iss = ssp.GetSecureStore(context);
    iss.SetUserCredentials(targetApplicationID, ssClaim, credentials);

    the above line of code is giving me an error that "Object reference not set to an instance of an object"

    even though every object is existing and even runnig with this Privilege "SPSecurity.RunWithElevatedPrivileges".

    The above code runs very well with a console application, but when I have used in a webpart, I'm getting the above error.

     

    Kiran

    Thursday, September 2, 2010 1:08 PM