views:

589

answers:

2

Here is our current setup. We have Active Directory configured (domain named mis1) that handles all of our authentication issues. We have our web applications setup for impersonation=true so that we can have our database queries called as the user logged in. For this particular application, IIS is set to Anonymous access to we can have Forms Authentication.

For our database security, we have local groups setup on the database server and add users into these groups as needed per application. For instance, we would have a "FancyPantsManager" group and a "FancyPantsUser" group for the same FancyPants application. We then setup SQL Server 2005 logins to map to these local groups on the server.

What I want to do is to present a login page for the user that authenticates off of AD and then if successful, goes to the database server to get their roles (by calling xp_logininfo) to store in the user's session.

So far I have the forms authentication successfully authenticating off of Active Directory by doing a p/Invoke on the LogonUser method from the avapi32.dll file. I then take the resulting token and generate a WindowsIdentity object and impersonate the user. The code looks like this:

Private Sub loginMain_Authenticate _
               (ByVal sender As Object, _
                ByVal e As System.Web.UI.WebControls.AuthenticateEventArgs) _
        Handles loginMain2.Authenticate

   ' Assume variables properly declared

   IsAuthenticated = LogonUser(UserName, LOGON_DOMAIN, UserPass, 
                               LOGON_TYPE, LOGON_PROVIDER, ResultToken)

   If IsAuthenticated

      ' Setup impersonation for validated user.
      WindowsId = New WindowsIdentity(ResultToken)
      IdentContext = WindowsId.Impersonate()

      ' Call stored procedure to retrieve roles using validated user for login.
      GetUserRoles(UserName)

   End If

End Sub

When I step through the debugger and enter my proper Id and password. I am authenticated, and looking at the WindowsIdentity object that is generated, it states my Id is "mis1\c07884" which is precisely what is needed for impersonation to get to the SQL Server. However, when the GetRoles method is called, I get the following error message:

System.Data.SqlClient.SqlException: Could not obtain information 
about Windows NT group/user 'c07884', error code 0xffff0002.

It seems to me that something is not occurring properly with the impersonation process. What am I missing?

A: 

An eye out to this question might help? Active Directory: Retrieving User Information

Will Marcouiller
Nah!... I guess this is not what you want, is it?
Will Marcouiller
Close, but I need to have an authorization token so that I can connect to the database, as well as save part of the ticket for the user's web session.
Dillie-O
A: 

Edited to remove irelevant content.

xp_logininfo. Looks like you invoke it passing in the account name as the user name w/o domain. Which actually explains why the error messages says c07884 not found and not mis1\c07884 not found as it should. The error 0xFFFF002 is probably error 2 ERROR_FILE_NOT_FOUND.

Right now the quickest fix is probably to pass the correct account name:

GetUserRoles(string.Format("{0}\\{1}"), LOGON_DOMAIN, UserName));

You should consider rewriting the procedure to retrieve the impersonated user info by calling x_logininfo with no arguments to return the info of the current user. Better still, just SELECT * FROM sys.login_token.

If all you nee din ASP is the group membership, you already have it in WindowsIdentity.Groups.

Remus Rusanu
The problem I've run into with the WindowsIdentity.Groups is that the groups are local to the database server, and not to the domain name as a whole. Will Groups be able to pull memberships off of individual servers and not domain wide?
Dillie-O
When I call GetUserRoles, the connection string is configured to use SSPI, which I'm assuming means it will take the impersonated credentials of the WindowsIdentity logged in, which for some reason comes back as just c07884 without the domain, is there a way to update the "name" associated with the login?
Dillie-O
IS the database host joined to the `mis1` domain (or is it joined to a domain that trusts `mis1`) ?
Remus Rusanu
Good question. I'm not sure at the moment. I want to say yes, but need to go talk to our Ops guys on that one.
Dillie-O