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