Pregunta

Tengo una base de datos SQL que la cadena de conexión fue codificada en una bolsa de propiedad Lo estoy cambiando para usar la aplicación Secure Store Service.

Ya creé el ID de la aplicación en la tienda con los campos y valores requeridos. Lo configuré para agrupar.

La cadena de conexión será la misma para todos los usuarios, y estoy tratando de leerlo con privilegios elevados.

Todavía tengo acceso denegado

La excepción se lanza aquí:

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

Mi todo código es así:

/// <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;
        }

¿Fue útil?

Solución

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.

Licenciado bajo: CC-BY-SA con atribución
scroll top