I have a C# web application that (in some configurations) allows the user to enter Windows credentials which it then uses to authenticate to a remote service. To accomplish this, we currently call LogonUser and use the resulting token to create a WindowsIdentity, which we then impersonate. It’s been working fine with no real problem.
Recently I was reading about web authentication and read that for basic authentication IIS uses LsaLogonUser to create the impersonation context. I kind of understand the difference between the two and it kind of sounds like we should be using LsaLogonUser, but I hate to make changes I don’t understand for an unclear benefit. On the other hand, the guys who work on IIS understand the Windows API better than I do.
So: Which function is more appropriate for a web application? Would you say it’s wrong to use LogonUser and why? Are there situations (network configuration, user permissions, etc) where one will work and the other won’t? Is it any kind of security risk to use LogonUser?
There are many questions in your question, here is a quick answer for all of them, followed by some details.
LogonUser. Here is a Microsoft Knowledge base article with sample code.LogonUser, there is nothing wrong with it. It is the function you should use most of the time.LogonUserdoes not support Kerberos Services 4 User (S4U), butLsaLogonUserdoes. On a more historical note,LogonUserused to require TCB privilege, but not anymore (except for Passport logons). There was a clever way around it anyway (look for “Another use for SSPI in that page).Now some details on answer 2, 3 and 4
It’s okay to use LogonUser
You should use LogonUser over LsaLogonUser if it supports your use case. Most of the time, it does, so you use LogonUser. LsaLogonUser works, but it has a lot of parameters, some are pointers to memory that must be in a specific format. In other words, LsaLogonUser was made by C developpers when packed structures and self relative pointers where… I don’t know. Cool ?
LsaLogonUser can give you a token without a password (S4U)
In Windows Server 2003 was introduced Kerberos Services for User (S4U). S4U allows you to call a KDC and get a token for a user, without providing a password. That token is a Identify token, it cannot be used to impersonate the user. LogonUser cannot give you that token but LsaLogonUser can.
Keith Brown explains what is S4U and how to use it better than I ever could.
In conclusion
There is only one use case were LsaLogonUser is better than LogonUser. But since WindowsIdentity provides a constructor for that (S4U), I don’t see why one would ever use LsaLogonUser in a .Net application.
Your code is good as it is 😉