Code-First Auto-Create SQL Server database on application start - asp.net

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?

Related

right place to have the connection string

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.

Give Asp.net mvc app permission to drop and create SQL Server Database

I am using SQL Server 2008 R2 and am facing a problem. The application that I have developed needs to be tested at client's site which is at different locality. So I plan to configure the client's machine once and then for any changes related to application I will just distribute a asp.net mvc deployment package which client can deploy on IIS. For that, I need to provide my asp.net application ability to drop and create database (through codefirst entity framework). In the present configuration, I am facing permission issue related to dropping the database. The Application somehow is unable to drop the database. Here is summary of IIS and SQL Server configuration that I am using.
For IIS, I have set the Application Pool Identity to "Local Service" as per the standard practice. The connection string in asp.net web.config file is given below.
connectionString="Server=.\SQLEXPRESS;Database=SomeDatabase;Trusted_Connection=true;User Id=someuser;Password=somepassword" />
For SQL Server Service, I have provided "Local Service" as log on, again providing the minimum access here for the service. For SQL Server Instance Logins I have defined the user and password and given complete authority ("sysadmin") role.
With this configuration in place I was expecting my IIS application to connect using the user and password created above and have the ability to drop and create the SQL Server database. But I am getting permission denied for Dropping Database. The Exception is given below.
System.Data.SqlClient.SqlException (0x80131904): Cannot drop the database 'SomeDatabase', because it does not exist or you do not have permission.
I have checked that the database exists so it boils down to permissions. Am I missing out some configuration ?
To be clear, your connection string is a bit malformed, and may not be behaving as you expect.
When you specify Integrated Security=true in your connection string, then Windows Authentication occurs. Any user id= attribute in the connection string will be ignored.
Switch to SQL Server authentication mode by dropping your Integrated Security=true attribute.
Server=.\SQLEXPRESS;Database=SomeDatabase;
User Id=someuser;Password=somepassword;
Further, the DROP DATABASE command can be executed by the database owner, a user who's a member of the db_owner role, or a user in a server admin role.
Add the database user someuser to the db_owner role.
EXEC sp_addrolemember 'db_owner', 'SomeUser';
Alternatively, if you determine that the account above should NOT be in this role (i.e. restrictive security environment, policies, etc), consider creating and using another account just for this purpose. This would likely mean maintaining another connection string. If the separation of users/roles is important enough for you, perhaps this second option will work.
I think that the real account being used on the Sql connection is the 'Local Service' because you defined Trusted_Connection=True in the connection string. Try to remove it and see what happens. If I'm not wrong, this parameter will make use of a Windows Integrated Account, the Local Service in your case.
While specifying credentials in the connection string, you either need to omit Trusted_Connection part or set it to False
Data Source =myServerAddress; Initial Catalog =myDataBase; User Id =myUsername; Password =myPassword;
OR
Server =myServerAddress; Database =myDataBase; User ID =myUsername; Password =myPassword; Trusted_Connection =False;
Refer http://connectionstrings.com/sql-server-2008 for more details.

Can't connect to database on server

I cannot connect to my SQL Server database when running app on server.
Everything runs fine when debugging but when I run on the server as ASPNET the user is unable to login.
I created the dataabse in a test project then simply connected to this db. My connection string is
Data Source=.\SQLEXPRESS;AttachDbFilename=C:\Temp\Barry\fsr\FSR.mdf;
Integrated Security=True;Connect Timeout=30;User Instance=True
So this asp app runs on IIS 5 and when deployed the initial select works fine as my gridview that I have a binding to shows data but when I run the program (update the db) I hit the following:
[SqlException (0x80131904): Cannot open user default database.
Login failed.
Login failed for user 'hostxxxxx\ASPNET'.]
I am not creating this database programmatically as mentioned previously, simply connecting to an existing database.
The database is located on my c: - but I have added user ASPNET. How can I add this db to the program as a resource rather than reference a copy on c:?
My first question is this: If you have control of the server, why are you using an attached database. From:
AttachDbFilename=C:\Temp\Barry\fsr\FSR.mdf
There is no reason to attach if you can control the server. Attach the database to the actual instance in SQL Server, not with the bastardized version you have above. The bastardized version is useful on an ISP that does not give you access to SQL tools. Beyond that, it is more work than it is worth.
The second problem you have is authentication. There are a couple of ways to handle this. The easiest is set up a SQL user to access the database. If every user will have login credentials, you can keep the Windows Authentication method, but you have to turn off anonymous access, so every user GETS authenticated. As long as anon is a choice in IIS, it will default to anon and you will have issues. The third way is to impersonate a user for database access. I guess the fourth is open your database wide open, but I don't suggest destruction of security to make something "work".
If you have your database on a server, you need to use a server-based connection string - something like:
Data Source=servername\SQLEXPRESS;database=FSR;
Integrated Security=True;Connect Timeout=30;
Your user needs to have a login on the server, and a user in the appropriate database, in order to connect successfully.
See the ConnectionStrings.com web site for a huge list of possible connection strings - and what their settings mean and how you can change those.
You need to get into your database and assign the proper privileges to the account that is trying to access the database, which in this case looks like the built-in ASPNET account. Instead of the ASPNET account, you should use the NETWORK SERVICE account. You can change this through IIS.

Attaching mdf file into sql server

Earlier mdf file was in app_Data folder, and application was working fine.
When I attached mdf file into sql server. I can execute queries. But when I try to use it from asp.net application it give following exception.
Cannot open user default database. Login failed.
Login failed for user 'domain\username'
So if I understand correctly you no longer specify the AttachDBFilename but instead you have attached the database 'for real' to an existing SQL Server instance.
since you are no longer conencting to your own personal RANU instance, your application must have proper credentials to connect to the SQL Server instance where you attached the database. The correct solution depends on a number of factors, but possible answers are:
create a SQL Server login for the ASP app pool identity and grant this loggin proper access to the required database. Use CREATE LOGIN [domain\user] FROM WINDOWS and CREATE USER [domain\user]. Better still, for extra credit, add the app pool identity to a security group and grant this security group the needed permission.
change the app pool identity to an indetity that has the proper permissions already granted
if the ASP application uses impersonation and the SQL Server instance is on a different machine from the ASP application, make sure your ASP app pool is allowed to do constrained delegation.
That error indicates that you are trying to use Intergrated Security. Depending on your version of IIS and your configuration, you are probably trying to connect to the database with the IUSR or NETWORK SERVICE accounts.
The simplest fix is to use SQL Authentication. Include a SQL account username/password in your connection string.

Recommended ways to create a new database from an ASP.Net application

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).

Resources