This is a long overdue follow-up to my Active Directory Authentication post. I had all the best intentions of quickly following this post up with a second post so this is long overdue. It’s been just over a year though so there are lots of cobwebs so this is going to be a stream of consciousness dump…
First, there are two books that I found indespensible and the best resources I could find for detailed information about integrating with Active Directory and Windows security. The LogonUser and SSPI approach I mentioned in my first post a year ago originated from these books.
- The .NET Developer’s Guide to Directory Services Programming
- The .NET Developer’s Guide to Windows Security
In an effort to just get some follow-up out there since I tend to get regular inquiries about my original post, Here’s a zip file of some sanitized code that includes the code for LogonUser, SSPI and a few other classes I used.
In the end I settled on LogonUser which seemed to give the best overall performance in a very decentralized, many sub-domain environment. There were also less anomalies as well. When using SSPI I found that if typical authentication took 140ms, some calls were taking 60.140s and 120.140s in one or two domains. This was rare and most likely a result of some sort of timeout and retry or fallback to another domain controller. I was not able to identify the root cause.
One side note regarding the LogonUse API. When the authentication type is set to “LOGON32 LOGON NETWORK” the LastLogon and LastLogonTimeStamp attributes on the domain controllers are not updated when authentication occurs. If you have any logic that relies on these attributes (For example if you to run a script against AD to check for user account inactivity), change the authentication type to “LOGON32 LOGON INTERACTIVE” to have these attributes updated as expected.
Lastly to test the differences between the three authentication types, I created a method to log detailed information about each authentication attempt including: elapsed time, samAccountName, domain, authentication result, user ip, domain server authenticated against (if I could figure it out), authentication web server. Without going into too much detail, I logged this info into a row in a database table on each attempt (this also inherently created a great resource for security auditing). This way I could query the data very easily to roll-up statistics based on which domain, what server, the IP subnet of the user, particular users, etc. Key to this though was to avoid any additional latency on the authentication request or a database dependency on the success of the authentication request, I created a BlockingQueue that waited for a log message to be placed on the queue and inserted it into the database. This happened out of band in another thread and if there was some failure, the queue would just continue to grow until the problem was resolved. This was very effective in measuring the performance of these different authentication methods.
Feel free to comment with any questions, I’ll do my best to recollect.






Hi!
I really liked your article! I’m implementing a very similar scenario for a web application that is accessed by users from different domains and DCs.
In the first part you mentioned the words ‘auto-login’, which caught my attention since that’s the way we’re trying to go.
Like in your case, we’re using IIS with Integrated windows authentication to bypass the authentication phase of the login process.
The problem is, because the other domains are not trusted inside the webserver’s AD, we can’t validate the users trying to log-in. IIS simply denies access to them.
Even if we try to find the users credentials in the any of the available LDAP servers (using a fixed user/pwd for navigation) we still have the problem of not knowing who the user is.
Does this make any sense to you?…
Thanks!
Joao,
yes this makes sense. As you said there must be a trust set up between all of the domains of the users trying to authenticate. I’m not quite following the last thing you said though about authenticating to these LDAP servers using basic credentials and not knowing who the user is. Are you still trying to get IWA to work while manually attempting to resolve who the user is to there other domains? In that case, yes it makes sense why that doesn’t work.
Thanks,
Mike