Question

MVC 3 (probably the same for 1 & 2), Server 2003, IIS 6, .NET 4, SQL Server 2005

I have a simple admin app that only 2 or 3 people will ever log into, so I don't want to bother with Forms Authentication, separate username/pw and all that. I want to simply have the user log in with their existing AD user/pw. But I want to connect to SQL Server via a dedicated account that already has appropriate permissions for the selected DB.

I've done this in classic asp with the following scenario

IIS: Enable anonymous Access: checked.  Username/pw dedicated account for the SQL Server DB
Integrated Windows authentication: unchecked
Digest authentication: unchecked
Basic authentication: unchecked
.NET Passport authentication: unchecked

The classic asp app accepts a posted HTML form, then authenticates via LDAP

' Establish connection
Set objConnection = Server.CreateObject("ADODB.Connection")

' Connection properties
objConnection.Provider = "ADsDSOOBJECT"
objConnection.Properties("User ID") = strUsername
objConnection.Properties("Password") = strPassword
objConnection.Properties("Encrypt Password") = True

' Open connection
objConnection.open "DS Query", strUsername, strPassword  ' user supplied user/pw

' Query Active Directory
strQuery = "SELECT cn FROM 'LDAP://" & strDomain & "' WHERE objectClass='*' "

Set objCommand = server.CreateObject("ADODB.Command")
Set objCommand.ActiveConnection = objConnection
objCommand.CommandText = strQuery

' Get recordset
Set objRS = objCommand.Execute

' If no record of user found
If objRS.BOF Or objRS.EOF Then

    ' User does not exist
    AuthenticateUser = False

Else

    ' User is authentic
    AuthenticateUser = True

End If

I want this same behavior in .NET, but without the HTML form. It seems possible that when the user visits a controller with an [Authorize] attribute:

[Authorize(Users = @"domain\user1, domain\user2, domain\user3")]

that they should be prompted to enter their AD user/pw (or not with IE, depending on the zone and auto-login options) then be authenticated, yet use the dedicated user in IIS to connect to the DB. How do I accomplish this?

I've always assumed impersonation was the way to go, so this is in my web.config:

  <system.web>
    <identity impersonate="true"/>
    <authentication mode="Windows" />

I tried adding this, but no help:

  <anonymousIdentification enabled="false"/>
  <authorization>
      <allow users="*"/>
      <deny users="?"/>
  </authorization>

I can get everything to work for me if I use Basic authentication, but that's only because my account also has access to the DB. If another user who is in that Users = list, but doesn't have access to the DB tries, they receive:

Cannot open database "Dbname" requested by the login. The login

failed. Login failed for user 'domain\user3'.

Obviously impersonation isn't doing its thing here.

So, this has to be a rather typical example of how to authenticate behind the firewall on your average windows network. What's the best approach? I've considered a custom AuthorizeAttribute using code similar to LDAP Authentication in ASP.Net MVC This seems closer to how things worked in the classic asp app, but for some reason I thought I could just get everything working with settings and configuation alone.

EDIT1:

After reading some of Barry Dorrans' Beginning ASP.NET Security last night, It appears that I can change the user of the app pool and have that be the user that hits the SQL Server DB. Is that right? Or is it the Anon Users in the web site settings that hits the DB?

Tried changing the app pool user, but the account isn't part of the IIS_WPG group. That's required, right?

EDIT2: With Basic auth checked, anon checked with specified user, I get the following:

User.Identity.Name: DOMAIN\jcurran
User.Identity.IsAuthenticated: True
User.Identity.AuthenticationType: Basic


WindowsIdentity.GetCurrent().AuthenticationType: Kerberos
WindowsIdentity.GetCurrent().Name: DOMAIN\jcurran
WindowsIdentity.GetCurrent().IsAuthenticated: True
WindowsIdentity.GetCurrent().IsAnonymous: False
WindowsIdentity.GetCurrent().IsGuest: False
WindowsIdentity.GetCurrent().IsSystem: False
WindowsIdentity.GetCurrent().ImpersonationLevel.ToString(): Impersonation


Thread.CurrentPrincipal.Identity.Name: DOMAIN\jcurran 

With Basic auth unchecked, anon checked with specified user, I get a blank page. Inspecting with fiddler yields:

HTTP/1.1 401 Unauthorized
Date: Thu, 06 Jan 2011 18:02:42 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 4.0.30319
X-AspNetMvc-Version: 3.0
Cache-Control: private
Content-Length: 0
Was it helpful?

Solution

Assuming you want to access the SQL server with Windows Auth, then changing the app pool identity is the way to go.

In web.config you'll need to set impersonate="false" or ASP.NET will try to use the client's credentials to connect to the database instead of the app pool's (i.e. it looks like impersonation is doing exactly what you asked it to do).

In IIS you must enable Integrated Windows Auth and you can disable anonymous access if you want.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top