How to do Active Directory authentication in Razor (cshtml)
active-directory, authentication, ldap, razor
Solution
Since this is an internal application, and you're looking for something simple, I would consider writing a single class to do the Active Directory authentication. You're going to need a couple things though, in order for this to work :
- A reference to `System.DirectoryServices.Protocols` in your project.
- The IP or DNS name of your Active Directory server. We'll call it `host` in the code below.
- The port it's running on (LDAPS will be port 636, basic LDAP will be port 389). We'll call it `port` in the code below.
- The Domain to which your users belong. We'll call it `domain` in the code below.
Now that you have that, you can wire this up to check the credentials from the request against your AD instance. I would try something like this :
// the username and password to authenticate
username = Request["username"];
password = Request["password"];
// define your connection
LdapConnection ldapConnection = new LdapConnection("host:port");
try
{
// authenticate the username and password
using (ldapConnection)
{
// pass in the network creds, and the domain.
var networkCredential = new NetworkCredential(username, password, domain);
// if we're using unsecured port 389, set to false. If using port 636, set this to true.
ldapConnection.SessionOptions.SecureSocketLayer = false;
// since this is an internal application, just accept the certificate either way
ldapConnection.SessionOptions.VerifyServerCertificate += delegate { return true; };
// to force NTLM\Kerberos use AuthType.Negotiate, for non-TLS and unsecured, just use AuthType.Basic
ldapConnection.AuthType = AuthType.Basic;
// authenticate the user
ldapConnection.Bind(networkCredential);
}
catch (LdapException ldapException)
{
//Authentication failed, exception will dictate why
}
}
Also, in the same way you'd communicate an authorization issue before, the `ldapException` can tell you why the call failed. If you want to display custom messaging, I would check the `LdapException.ErrorCode` property, and maybe create a case statement of return messages based on the error codes.
Or, you could just output `LdapException.Message` directly to the page - either way, that will at least dictate to the user why their login didn't work.
Problem
I am doing a simple website with Razor. Currently, I have database-based authentication that works, as follows: In _AppStart.chtml: ``` WebSecurity.InitializeDatabaseConnection("db_connection", "users", "id", "username", true); ``` In login.cshtml page: ``` username = Request["username"]; password = Request["password"]; if (WebSecurity.Login(username, password, true)) { Response.Redirect("/admin"); } else { errorMessage = "Login was not successful."; } ``` In protected CSHTML pages, I have the following at the top of a page: ``` if (!WebSecurity.IsAuthenticated) { Response.Redirect("/login.cshtml"); } ``` Everything is pretty simple and works well. Now I would like to add authentication with AD. I don't know how to do it. I came from the Java world with many years of experience. For this simple website, I do not need MVC architecture. I need simple things similar to the above (if possible). I need to do authentication just within the login.cshtml file. I googled a lot and am unable to find a tutorial (so that I can copy and paste) for what I need. Any pointers or help is really appreciated! Thanks and Regards Update: This application sits on the internal network. Update 2: Here is the code I have after successfully implemented X3074861X's code ``` if (IsPost) { username = Request["username"]; password = Request["password"]; var domain = "domain"; var host = "host"; var port = "389"; LdapConnection ldapConnection = new LdapConnection(host + ":" + port); try { // authenticate the username and password using (ldapConnection) { // pass in the network creds, and the domain. var networkCredential = new NetworkCredential(username, password, domain); // if we're using unsecured port 389, set to false. If using port 636, set this to true. ldapConnection.SessionOptions.SecureSocketLayer = false; // since this is an internal application, just accept the certificate either way ldapConnection.SessionOptions.VerifyServerCertificate += delegate { return true; }; // to force NTLM\Kerberos use AuthType.Negotiate, for non-TLS and unsecured, just use AuthType.Basic ldapConnection.AuthType = AuthType.Basic; // this is where the authentication occurs ldapConnection.Bind(networkCredential); //check local database to make sure the user is one of we allowed if (WebSecurity.Login(username, "fixed-password, just to check whether someone is on the list of allowed people", true)) { Response.Redirect("/admin"); } else { errorMessage = "Login was not successful."; } } } catch (LdapException exception) { //Authentication failed, exception will dictate why errorMessage = "Login was not successful."; } ``` Some explanation. I dont have control over the AD and so I can only authenticate users against it. I still have a little local database that indicates who can access the app. Everyone with access to the app has the same rights. Thanks and credit goes to X3074861X.