Question

I have a sql database which connection string was hardcoded on a property bag I am changing it to use the secure store service application.

I already created the application id on the store with the required fields and values. I set it to Group.

THe connection string will be the same for all users, and I am trying to read it with elevaged privileges.

I still get access denied

The exception is thrown here:

using (var credentials = secureStoreProvider.GetCredentials(applicationId))

My all code is like this:

/// <summary>
        /// Gets the database server and database name from the property bag
        /// </summary>
        /// <returns></returns>
        public static string GetDMSConnectionStringFromSecureStore()
        {
            var entityBuilder = new EntityConnectionStringBuilder();
            SPSecurity.RunWithElevatedPrivileges(delegate
            {
                try
                {
                    const string providerName = "System.Data.SqlClient";
                    var dic = GetCredentialsFromSecureApp(Constants.SecureStore.ApplicationId);
                    var serverName = string.Empty;
                    var databaseName = string.Empty;
                    var databaseUserName = string.Empty;
                    var databasePassword = string.Empty;

                    foreach (var item in dic)
                    {
                        if (item.Key == Constants.SecureStore.DatabaseServerField)
                        {
                            serverName = item.Value;
                        }
                        if (item.Key == Constants.SecureStore.DatabaseNameField)
                        {
                            databaseName = item.Value;
                        }
                        if (item.Key == Constants.SecureStore.UserNameField)
                        {
                            databaseUserName = item.Value;
                        }
                        if (item.Key == Constants.SecureStore.PasswordField)
                        {
                            databasePassword = item.Value;
                        }
                    }

                    // Initialize the connection string builder for the underlying provider.
                    var sqlBuilder = new SqlConnectionStringBuilder
                    {
                        DataSource = serverName,
                        InitialCatalog = databaseName,
                        UserID = databaseUserName,
                        Password = databasePassword
                    };

                    // Build the SqlConnection connection string.
                    var providerString = sqlBuilder.ToString();

                    // Initialize the EntityConnectionStringBuilder.
                    entityBuilder.Provider = providerName;
                    entityBuilder.ProviderConnectionString = providerString;
                    entityBuilder.Metadata = @"res://*/DMSModel.csdl|res://*/DMSModel.ssdl|res://*/DMSModel.msl";
                }
                catch (Exception ex)
                {
                    LoggingService.LogError(LoggingCategory.Security, ex);
                }
            });

            return entityBuilder.ToString();
        }

        private static SecureString CreateSecureString(string unsecureString)
        {
            var secureString = new SecureString();
            foreach (var c in unsecureString/*.ToCharArray()*/)
            {
                secureString.AppendChar(c);
            }
            return secureString;
        }

        public static SPSite GetCentralAdminSite()
        {
            var adminWebApp = SPAdministrationWebApplication.Local;
            if (adminWebApp == null)
            {
                throw new InvalidProgramException("Unable to get the admin web app");
            }

            SPSite adminSite;
            var adminSiteUri = adminWebApp.GetResponseUri(SPUrlZone.Default);
            if (adminSiteUri != null)
            {
                adminSite = adminWebApp.Sites[adminSiteUri.AbsoluteUri];
            }
            else
            {
                throw new InvalidProgramException("Unable to get Central Admin Site.");
            }

            return adminSite;
        }

        private static string GetStringFromSecureString(SecureString secStr)
        {
            if (secStr != null)
            {
                var pPlainText = IntPtr.Zero;
                try
                {
                    pPlainText = Marshal.SecureStringToBSTR(secStr);
                    return Marshal.PtrToStringBSTR(pPlainText);
                }
                finally
                {
                    if (pPlainText != IntPtr.Zero)
                    {
                        Marshal.FreeBSTR(pPlainText);
                    }
                }
            }

            return null;
        }

        public static Dictionary<string, string> GetCredentialsFromSecureApp(string applicationId)
        {

            var credentialMap = new Dictionary<string, string>();

            // Get the default Secure Store Service provider.
            var provider = SecureStoreProviderFactory.Create();
            if (provider == null)
            {
                throw new InvalidOperationException("Unable to get an ISecureStoreProvider");
            }

            var providerContext = provider as ISecureStoreServiceContext;
            if (providerContext != null)
                providerContext.Context = SPServiceContext.GetContext(GetCentralAdminSite());

            var secureStoreProvider = new SecureStoreProvider
            {
                Context = SPServiceContext.GetContext(GetCentralAdminSite())
            };

            using (var credentials = secureStoreProvider.GetCredentials(applicationId))
            {
                var fields = secureStoreProvider.GetTargetApplicationFields(applicationId);
                for (int i = 0; i < fields.Count; i++)
                {
                    var field = fields[i];
                    var credential = credentials[i];

                    var decryptedCredential = GetStringFromSecureString(credential.Credential);

                    credentialMap.Add(field.Name, decryptedCredential);
                }

            }

            return credentialMap;
        }
Was it helpful?

Solution

I found the problem myself, Robert inspired me :)

  1. On the secure store service application, I selected it and clicked on the administrators button, I added the App Pool account used by the calling application. It did not work.

  2. I added the Web Service App pool account It did not work.

  3. On the target application, I edited it, and on the members section (last step), I added the Web App Pool account This worked.

Licensed under: CC-BY-SA with attribution
Not affiliated with sharepoint.stackexchange
scroll top