what does 'run the ASP.NET worker process with dbo privileges' mean? - asp.net

I am having issues implementing SqlSiteMapProvider using the Wicked Code article. I am using VB.NET and SQL Server 2008 - and the OnSiteMapChanged event is not firing (the SqlDepdencyCache just seems to simply be not working at all).
The article states "You also need to run the ASP.NET worker process with dbo privileges for SQL Server 2005 cache dependencies to work automatically.)"
I don't understand what this means. I know what the ASPNET user account is and that it runs aspnet_wp.exe which is basically the ASP.NET run time as I understand it. I know what DBO privs are on SQL. But my SQL and web servers are on different machines, and ASPNET is not a domain account. And it seems crazy to make it one to try to simply get the SqlDepdencyCache to work, and I have trouble believing everyone is doing this?
Anyone have any clue what I'm missing here?
Thanks very much
EDIT: I FOUND MY ISSUE!!! SET NOCOUNT ON INSIDE MY STORED PROC WAS CAUSING IT!! BEWARE AS THIS IS NOWHERE IN THE MSDN DOCUMENTATION!!!!

Your worker process identity needs to be changed to either a domain user OR a user with a matching username/password on both the web and database servers. The SQL Server would also need Windows authentication (or Mixed authentication) enabled.
Under IIS 5 (Windows XP/2000), you need to modify the ASP.NET Process Identity in the machine.config file.
Under IIS 6 / 7 (Windows Vista/7/2003/2008/R2) you should just be able to modify the Application Pool identity. If this doesn't work, enable <identity impersonate="true" /> in your web.config.

SqlDependencyCache uses SqlDependency and SqlDependency deploys at runtime a set of services, queues and stored procedures in your database as part of its infrastructure. You can read this article on more details what really happens The Mysterious Notification.
When you create your site map provider, you provide a connection string. This connection string specifies either a SQL login and password, or it specifies that SSPI (or Trusted, or Integrated) Authentication should be used. When a user and password are provided then this user is used to log in into your application database (the ASP database). When SSPI is used then the conenction is made using the ASP thread identity, which is either the app pool identity or the impersonated user identity. Whichever login ends up being used, this login must have the priviledges necessary to deploy the SqlDependency infrastructure (create a queue, create a service, create a stored procedure). The simplest way is to simply make this login's user in the database member of the db_owner role (which is the correct wording for what the article calls 'dbo priviledges').
So depending on yoru connection string, your app pool identity and your impersonation settings, the database user that corresponds to the login used by the map provider must be added to the db_owner role. I can't tell what you need to do, because it all depends on the variable factors enumerated above.

Related

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.

ASP.NET accessing a SQL Server in a different server

I have installed a new web application that access a SQL Server database in a different server. I'm using Windows Authentication and get the error of:
Login Failed for user XXX
When I try to set identity impersonate="true" in the web.config file, it just throws an error
Login Failed for anonymous user
Also, I'm using forms authentication to validate users from my website and using a different application pool.
Update: connection string Basically like this:
Data Source=myServerAddress;Initial Catalog=myDataBase;Integrated Security=SSPI;
Update:
My Virtual Directory has Anonymous Authentication and Windows Authentication enabled.
Typically ASP.NET runs as an anonomous account. In order to access a remote SQL Server using integrated authentication (SSPI), you'll need to have a bit more "permenant" presence. Easy way would be to shift the app pool to use the NETWORK SERVICE built-in account. Slightly trickier would be to use a named account. On the SQL server side of the equation you will need to give the same account -- either matching user/pass or NETWORK SERVICE -- proper permissions to your database.
Your DBA should be able to help.
It is difficult to provide you with an exact answer because you have not provided your connection string or info on your SQL Server config. Your best bet is to look at the IIS configuration and work out what user is attempting to access the different SQL Server. You then need to give this account access to the database. This is a common problem and most of the changes need to happen in SQL Server unless you can change the account that the web server is running under.

Preferred DB Connection for ASP.Net

What's the preferred (best practice) means of connecting an ASP.Net Website to a database? I doubt it's as simple as using Trusted-Connection and giving the NT-Authority accounts access.
What do y'all do? Assuming a clean install of SQL Server (2008), what do you do to configure access to the database for a website?
I usually run ASP.NET app pool as a separate account (not NT AUTHORITY\NETWORK SERVICE) and use Windows authentication to access the SQL Server. This method has the advantage of not storing the password in config files.
Steps:
Create a user account to run your ASP.NET application on.
Create an application pool in IIS and run it on the created account.
Assign NTFS permissions that your application needs to the account.
Grant permission to login on SQL Server.
Assign the appropriate database roles to the created login.
This will work for many apps. For more complex security environments, you might need more sophisticated strategies.
I used to use trusted connections, but ended up feeling that that sometimes I ended up having to grant too many privileges to the service account used for the connection/app pool. Now I use SQL Server accounts and set up the application to encrypt the connection strings during Application_Start if they aren't already encrypted. In fact I encrypt any section that may contain user credentials. I use an appSetting to determine whether the encryption code runs so I don't encrypt my settings in the development environment.
I also use SQL Server accounts, just find it simpler to do and to troubleshoot.

ASP.NET web app can't use multiple impersonation for authenication

I have a asp.net app (uses windows authentication for access) which (stipulated by the security team) needs to connect to a remote SQL Server 2005 using integrated security.Because of the fact that it is remote SQL server I needed to impersonate a custom account (impersonating the original caller would not work) via :
<identity impersonate = "true" userName="domainname\user" password="password" />
This workes fine. The rub is my app also connects to an SSRS server for reporting needs using the ReportViewer control. The report server is on a separate server and the security team mandates that all calls to this server must be using the original window's account for auditing purposes. It seems my only option was to to try and separate my app into folders and use a "location" tag in my web.config and use separate identity tags. Such as:
<location path="Reporting">
<system.web>
<identity impersonate = "true"/>
</system.web>
</location>
Note: no username and password specified which means it should impersonate the original caller.
However to make matters even more complicated my app is a Masterpage/content page app. The master page makes calls to SQL to populate menus and such. Bottom line is the dual impersonation track is not working. I am ready to throw my hands up and declare that that this can not be done. If there was a way where I could have the app impersonate the original caller which would satisfy my SSRS auditing needs yet make connections to SQL server as the custom domain account. I cannot use SQL authentication: not allowed although that would solve this issue.
Have you tried the following setup:
Set impersonation to true. This is necessary for authentication into the application and for access to the SSRS to use current user logged in.
Use one connection string to SSRS that has Integrated Security set to true, so that the impersonated user passes straight through.
Use a second connection string, with the custom user name and password hard coded into the connection string. You can encrypt the connection string section of the web.config so that it isn't visible to human eyes, but the framework will automatically decrypt this on the fly when creating a connection.
I have a similar situation (need a specific account to retrieve specific data, but the general impersonation for the rest of the service functionality) and this setup is working.
EDIT: The general syntax for encrypting your web.config from the command prompt is:
aspnet_regiis -pef "connectionStrings" [PhysicalPathToApplication] -prov "DataProtectionConfigurationProvider"
Encryption is done on a machine per machine basis, so the encryption will have to be done on the specific server. You can pull up more documentation on this if needed.
You should be able to switch the impersonation on and off, so you can go back to using the default account running the site. I will have to check, it's been a while since I have done it.
This looks like a start as to how to do it:
System.Security.Principal.WindowsImpersonationContext impersonationContext;
impersonationContext =
((System.Security.Principal.WindowsIdentity)User.Identity).Impersonate();
//Insert your code that runs under the security context of the authenticating user here.
impersonationContext.Undo();
Essentially you just impersonate the appropriate user for the calls you need, and then "undo" the context and turn it off. It goes back to the default user after that.
Here is a link to the windows identity class:
http://msdn.microsoft.com/en-us/library/system.security.principal.windowsidentity.aspx

How to get ASPNET to be recognized as a Trusted Connection by SQL Server 2005

Here's the situaiton. I'm working on developing a new website to access an old database. This is a DoD installation so there's lots of security around.
The current application is written in classic ASP, VBScript and some javascript. The new systems is ASP.NET.
Accessing the database in the old system meant hitting the server with your own credentials (domainname\username). Now I'm trying to test some of the early development I've done. When I used Cassini (under VS2008), I had no trouble getting to the database because ourdomain\myusername registered with the SQL Server instance as a trusted connection. Due to security aspects that I have to write, Cassini can't serve as a test server anymore - I have to use IIS (we have security card readers here). Cassini can't handle them.
So when I went through all the problems of getting the appropriate accounts added to Administrators on my local pc so that I could debug in VS2008 while using IIS, I tried to connect to the database and I was rejected because MYPC\ASPNET was not a trusted connection.
Altering the existing database is out of the question. Hard coding usernames and passwords for access to the database is out of the question.
I asked the DBA if he could add MYPC\ASPNET to of the domain groups so that SQL Server could see it as a trusted connection (since MYDOMAIN\MYNAME was in a group that was seen as a trusted connection). He tells me that is not technically possible.
In the end there are going to be three or four machines (mine, another developer, the eventual live web server and a future test web server) who's ASPNET accounts are going to be hitting our two SQL servers (live and test).
What do I have to do to make the existing SQL server see me as Friend and not Foe? I looked at impersonation but I get the impression it's not compatible with our system - the business rules make a call to a common routine to create a SqlConnection object and open it (maybe even a SqlTransaction object to go with it) and this object is used for the rest of the business rules and data-access layer until it's done. It didn't look like impersonation would persist once the SqlConnection was opened (and passed, ByRef back to the calling routine)
Thanks in advance for any advice.
You have two options:
Run your web application in an application pool configured to run in the context of a domain account
Use impersonation and configure your web application to use windows authentication only
Use Impersonation
As has already been suggested you should use impersonation.
However if your SQL Server is running on a different machine than your web server then impersonation will not suffice as the credentials of the user will not be delegated to the SQL Server (server hop). In that case you will have to either enable delegation in the AD or create a non-Windows login on your SQL Server and use that instead (this will not work if your SQL Server actually uses the Windows login for access control to tables etc.).
Sounds like you want to impersonate the client who is accessing your web site correct? Have you tried to use impersonation or are you assuming it won't work?
Edit
As Albert points out, impersonation requires the user to be authenticated using Windows authentication. You will want to disable Anonymous Access, and enable Windows Authentication in IIS Management tool.

Resources