Working with Azure web role that communicates to a SQL Azure database. Currently when I generate an edmx file for the SQL Azure database the connection strings + the username password are added to web.config file. I did a search and there were several entries on how to encrypt web.config/how to use that to switch between dev and prod but I am thinking of moving conn string out of web.config.
Is there a way by which I can move the connection string to the service definition file? Is that a recommended approach? If I move the connection string elsewhere can I still use the edmx and generated objectcontext classes (cause my existing code uses the automatically generated entity class).
It is best to move your connection strings into service config file. This allows you to switch over to a different SQL Azure database w/o redeployment. Switching to a different SQL Azure database w/o redeployment is useful when one has crashed or is timing out and you have a backup ready on a different server to switch over to.
You will need to initialize your object contexts by providing the connection string separately however.
Use the RoleEnvironment.IsAvailable to find out if you're running under Azure and the following code to read the setting in .cscfg:
var connectionString = RoleEnvironment.GetConfigurationSettingValue("ConnectionString");
I recommend having the connection string in both places, Service Configuration file (.cscfg) and Web.config. Where I also recommend from the beginning to have your web role able to run outside an Azure environment. It will impact your productivity in the long run. Especially with daily development where you do small changes and need to run the project locally to verify. Running your service locally in IIS, IIS express or Cassini (the codename for the Asp.net env) is currently faster than running your project in the local azure emulator (the devFabric).
Regarding your second question about storing the username and password. It all depends on the level of security that you're looking for. The information stored inside your .cscfg are transmitted over https and secured in the Azure cloud the same way your application is secured. That being said, I would store the TEST account credentials in the project for testing and would only put the PRODUCTION storage account credentials in the .cscfg at deployment time to the public/production service.
Related
I've had some recent difficulty with SQL Server not liking the default AppIdentityUser for logins, so I went ahead and created a custom DB user with write access.
But it made me wonder - is this the best approach?
I was wondering what the best SQL Server login approach would be for Asp.Net Core. I know there's a question similar to this for normal .NET, but you can't encrypt a Core web.config/appsettings.json (well, in a quick and straightforward manner).
Here are the options as I see them:
Connect via SQL Server ID that is stored in appsettings.json.
Pro: Already configured.
Cons: Password in web.config/appsettings.json; have to specifically configure SQL Server ID. Not centrally revokable.
Connect via user NT ID via ASP.NET "AppIdentityUser".
Pro: No passwords in appsettings.json.
Cons: Not centrally revocable. Seems to be restricted to the server name for user.
Connect via Active Directory user.
Pro: Easily revokable.
Cons: Active directory user password in appsettings.json. Could be bad if somebody accidentally reuses that user in another application in the company, and that user gets breached.
Are there other options that I'm missing? Which of these options are used in which situations? Which are more standard? Are there pros and cons that I'm not thinking about?
You should absolutely use a custom SQL Login to connect to the database. Under the hood, the SQL Login could be tied to a local account, service account, network account, etc. It doesn't actually matter.
The real issue you seem to be having here is in not wanting (rightly) to expose login credentials in plain text. I'm not sure why you keep referring to Web.config here, as ASP.NET Core doesn't use that. Instead, there's various configuration providers that can be optionally utilized. By default, ASP.NET Core (at least since 2.0) adds a JSON config provider that looks for appsettings.json and appsettings.{environment}.json in your project, a command-line configuration provider, a user secrets config provider, and finally an environment variable configuration provider.
The last two are the most interesting for your circumstances. In development, you should use user secrets. In production, you should use environment variables. However, neither stores secrets in an encrypted way. The benefit to either approach is that the secrets are not in your project, and therefore also not in your source control. Even though neither is encrypted, it's not as big of a concern as you might think. Getting at the secrets in either would require direct access to the server/development machine. Additionally, user secrets is by default tied to a particular user account, accessible only to that user, and environment variables can be set up the same way. Therefore, someone would need to both gain access to the machine and gain access to the particular account. That's actually a pretty high bar, and if it were to occur, exposing a database password is really the least of your concerns at that point.
Nevertheless, if you want true encryption, you have the option of using Azure KeyVault. KeyVault can be used whether or not your application is actually hosted in Azure, and while it's not free, it's exceedingly cheap.
Finally, you can always create your own config providers or source third-party ones. For example, while the default JSON provider doesn't support encryption, you could potentially write one that does.
As the title says, I want my application automatically create the database on application start. But, I would like that on the production server. I have a dynamic connection string generator class which handles the Initial Catalog value. I also have a database user on the server which has DbCreator and SysAdmin roles configured. I am using that database user on the dynamic connection string the app is creating on the app start phase.
I still couldn't manage to see an auto-created database on the server, with that configuration. Also, not being able to find any production scenario examples for CreateDatabaseIfNotExists on my searches, a question came up: Did I figure that out wrong?
Is the CreateDatabaseIfNotExists initializer works only for LocalDB?
Is it possible to encrypt a database connection string and deploy it to a Windows Azure Website? (NOT a Windows Azure Web Role) If so, how?
The reason I ask is because I can't find examples or documentation anywhere as to how to perform this specifically with Azure Websites. (I'd like to use the "Shared" web site mode)
I have found the following resources, which come close to what I want, but utilize Web Roles instead of Websites:
http://archive.msdn.microsoft.com/pkcs12protectedconfg
http://blogs.msdn.com/b/windowsazure/archive/2010/09/09/securing-your-connection-string-in-windows-azure-part-3.aspx
The proper way to use connection strings on Azure Websites is to add "debug" connection strings to your web.config file (and by "debug" it can be a local db/storage or any string that is safe to share - empty string).
On the Azure portal go to your Azure website --> CONFIGURE tab and under connection strings sections add your actual connection strings with the same names as used in your web.config file, there the connection string are saved as encrypted strings.
The website code will get the proper connection string you set in the Azure portal.
Our ASP.Net application uses SQL Server 2008. Most of the time the application connects to SQL Server using a SQL account with very limited access rights.
However once in a while we need to be able to create a new database on the fly. As such we need elevated permissions and I am a little nervous about storing this connection string in Web.config, which may be in a DMZ.
We are considering writing a Windows service to run on the SQL Server machine (i.e. not in the DMZ) which will monitor a table for requests to create a new database, but it seems like overkill.
Any suggestions for alternatives or recommended practices?
You can store the connection string in the registry and protect that by limiting access to the specified registry keys. That's one of the ideasI ran across back in .Net 1.1 as a reccomendation from Microsoft. The concept is still the same in 2.0 and up. Here's a link to the documentation.
http://msdn.microsoft.com/en-us/library/aa302406.aspx
It sounds like you're already concerned about security, so I'm guessing you've read through or at least run across the "Building Secure ASP.Net applications" section of the MSDN library. The link above is in the how-To section of that guide. Hopefully this is helpful.
Also, if you DO store your connection info in the web.config, at a minimum, encrypt those portions.
And I just ran across this. Probably more like what you were looking for.
http://msdn.microsoft.com/en-us/library/aa302388.aspx#secnetch08_storingsecrets
If you are using mixed mode authentication in your database connection strings (I.E., username and password) then you should encrypt the web.config connectionStrings element.
What about using a stored procedure to create the database? I haven't tried it; the one part I'm worried about is specifying the database name through a variable. By using the stored proc, you only need to grant your web id execute access on the stored proc.
Another option would be to create a console app (instead of a service). Then use a job scheduler to run the job every 15 or 30 minutes or upon request if you have a capable scheduler. That will be much simpler than writing a service; it just isn't an "instant" process. I do this for some Active Directory work that triggers off of web site updates (I didn't want to give my web id Domain Admin priveleges).
Best practice says to keep my web app and database on separate machines, but when doing that it seems I can't get a clear explanation on how best to make this connection. Whil windows auth is the recommended authentication, I don't see how to make a trusted connection . Must I use impersonation to have my application connect to a db server?
Are most people simply using SQL authentication in this case?
Both machines are on a virtual cloud network.
If both computers are in the same domain, I'd use Windows Authentication for the SQL connection. To set it up:
Create a domain account to use for the app.
Give the id the absolute minimum priveleges necessary to host the site on the web server. For example, it must have read access to the web site itself, write access only to folders updated by the web site, etc.
Change IIS so that the domain account is used to run the app. In IIS6 & IIS7, you do this through the application pool. In IIS5, you have to change the settings in the machine.config or in the web.config for the ProcessModel.
All calls to the database will be done through this domain account; you won't have to setup impersonation. In fact, if you are using SQL authentication today, the only change you need to make is to the database connection string; no code changes are needed.