I had to review some code today for an intranet site which was a javascript form with a C# WebAPI which sends the AD username and password (during login) to the backend and then logged in as that user against AD to check validness. (This is all on-prem).
My comments was that this was equal to making a form with a facebook logo and a username and password and ask users to log into your site using this and then log in yourself in facebook to check if the facebook credentials are valid. So fishing and man-in-the-midde alike and if we have all AD credentials of all users in our web application it would make it possible to login as that user everywhere and do everything.
However… discussion starts with the dev team and the argument is
- it works so why not (nothing can go wrong it is intranet)
- examples are also on stackexchange e.g. here:
Validate a username and password against Active Directory?) . So for this example for instance i assume this is only used specific cases but never in web cases - when you would write a desktop application in some language you would also need to validate yourself against AD in some way.
- this is perfect example of impersonation: we impersonate every user (where i would think more in the line of How to pass Windows Authentication credential from client to Web API service)
- if we ever going to extend our program to be a point where a user can change his password for ad we will need the new password (and a domain admin credentials) so this the same (where i would think you would always reset etc)
So that brings doubt. What I would think is (for AD not ADFS obviously)
- User logs in Windows
- User opens browser to URL
- IIS is configured with a site with Windows Authentication turned on
- Browser and IIS do the negotation (where Browser communicates with Windows Layer)
- User is valid or not > continue
As far as I know that is the best practice (gazillion links on stackexchange e.g. proper implementation of "windows" authentication in web api? and the web e.g. https://support.microsoft.com/en-us/help/323176/how-to-implement-windows-authentication-and-authorization-in-asp-net )
2
Answers
Applications should not be able to intercept user password.
So modern web and mobile applications separate authentication processes to SAML IdPs or OAuth2 Authorization Servers / OpenID Providers.
And native windows application can use Kerberos if the clients and the applications are both domain-joined.
All of above technologies enable an application to obtain verified user identities while eliminating the need to transfer username and password directly to the application.
That’s not an accurate analogy because of the issue of trust. Your company is not Facebook.
Your application is asking your company’s employees for their credentials to your company’s internal Active Directory. There is trust there. This is more like a website run by Facebook asking for your Facebook credentials.
That’s not to say there are no security concerns. Windows Authentication is the best way, not only because you’re not sharing the password with any other application, but because of ease of use. If properly setup, users are automatically logged in without the need to type in their username and password. That makes for happy users.
However, that doesn’t work if you need to authenticate to an external domain. That’s where I have setup a login form to collect an AD username and password. A couple of our websites need to allow users from external AD domains to login (where there is no AD trust), so I take the username and password over HTTPS and authenticate against the external domain via LDAPS. However, we don’t store the password. Once we’ve verified the credentials with the external domain, we create our Forms Authentication token with the username, and forget the password.
If you are storing AD passwords in your own database, then I think that’s the biggest problem. If anyone gets a hold of that database, then all of your users can be impersonated anywhere else in your organization.