Thursday, March 8, 2012

LDAP Authentication using C#


LDAP stands for Light Weight Directory Access Protocol.
Below source is an example to redirect to “newuser.aspx” incase if the user has browsed the web application for the first time.
In “Global.asax.cs”, under “Session_Start” event application checks if the requesting user is already authenticated before and added in DB.
If the user is available, application doesnot restrict where as if the user is new whose details will not be available in DB application redirects to “newuser.aspx”.
In page load of “newuser.aspx”, application connects to LDAP server and gets the details of the user based on SID (User Security Identifier) and logs the details in database.
Global.asax.cs
void Session_Start(object sender, EventArgs e)
    {
        // Code that runs when a new session is started
        Authenticate.User objUser = Authenticate.UserDB.GetUser(Request.ServerVariables["LOGON_USER"]);
        if (objUser == null)
            Response.Redirect("NewUser.aspx");
    }

Authenticate Assembly
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Authenticate
{
    public class ActiveDirectory
    {
        private static string SidToHex(System.Security.Principal.SecurityIdentifier securityIdentifier)
        {
            // determine the length of the security identifier (in bytes) so that we can turn it into a byte array
            int binaryLength = securityIdentifier.BinaryLength;

            // create a byte array of that length
            byte[] byteArray = new byte[binaryLength];

            // populate the byte array with the binary form of the security identifier
            securityIdentifier.GetBinaryForm(byteArray, 0);

            // setup a stringbuilder, with the default starting and max size to be twice the length of the byte array
            // which will allow two characters per byte
            System.Text.StringBuilder retval = new System.Text.StringBuilder(binaryLength * 2, binaryLength * 2);

            // loop through each of the spots in the byteArray, converting each to the string hex value
            foreach (byte bt in byteArray)
                retval.Append(bt.ToString("X2"));

            // return the new string
            return retval.ToString();
        }

        //To get User based on SID
        public static User GetUser(System.Security.Principal.SecurityIdentifier sid)
        {
            //connecting to LDAP Server and finding user based on sid
            System.DirectoryServices.DirectoryEntry objDirectoryEntry = new System.DirectoryServices.DirectoryEntry("LDAP://<SID=" + SidToHex(sid) + ">");
            objDirectoryEntry = new System.DirectoryServices.DirectoryEntry("LDAP://" + (string)objDirectoryEntry.Properties["distinguishedName"][0], null, null,
    System.DirectoryServices.AuthenticationTypes.Secure | System.DirectoryServices.AuthenticationTypes.ReadonlyServer);
            //reading the user details
            User objUser = new User()
            {
           //prperty names as per how they are added in LDAP
                Name = objDirectoryEntry.Properties["FirstName"].Value.ToString(),
                EmailID =
                    objDirectoryEntry.Properties["mail"].Value.ToString()
            };
            return objUser;
        }

    }
}

NewUser.aspx.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class NewUser : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            //get user object, reading details from active directory
            Authenticate.User objUser = Authenticate.ActiveDirectory.GetUser(Request.LogonUserIdentity.User);

            //setting the user name
            objUser.Name = Request.ServerVariables["LOGON_USER"];

            //Adding the user to the binary file, so that when the same user
            //logins again, application can authenticate using binary file
            Authenticate.UserDB.AddUser(objUser);
        }
    }
}

No comments: