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.





