Active Directory Login assistance-Collection of common programming errors
I’m not really sure if this is a question for here or not, please let me know if I must post it else where. I followed the steps and code given in this Microsoft tutorial and everything is working fine as far as logging in goes.
The problem a few users have submitted is that they can see other users data when they log in and click around.
EG: Joshua logs in on his machine and then Craig logs in on his machine as well (Separate machines). For some reason unbeknownst to me, Joshua can sometimes see Craig’s data and Craig can sometimes see Joshua’s data (Which should not happen).
I have a feeling it has something to do with Sessions? (But again, I am not sure and am fairly new to .Net and C# using AD)
Here is My code after following the tutorial above, do you notice anything that I have done incorrectly OR should do better OR anything I need to add?
LOGON CODE BEHIND:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using FormsAuth;
using System.Web.Security;
namespace FormsAuthAd
{
public partial class Logon : System.Web.UI.Page
{
public string fullname;
protected void Page_Load(object sender, EventArgs e)
{
}
public void Login_Click(object sender, EventArgs e)
{
string adPath = "LDAP://MyServerIP"; //Path to your LDAP directory server
LdapAuthentication adAuth = new LdapAuthentication(adPath);
try
{
if (true == adAuth.IsAuthenticated(txtDomain.Text, txtUsername.Text, txtPassword.Text))
{
fullname = adAuth.getFullName();
string groups = adAuth.GetGroups();
//Create the ticket, and add the groups.
bool isCookiePersistent = chkPersist.Checked;
FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(1, txtUsername.Text, DateTime.Now, DateTime.Now.AddMinutes(60), isCookiePersistent, groups);
//Encrypt the ticket.
string encryptedTicket = FormsAuthentication.Encrypt(authTicket);
//Create a cookie, and then add the encrypted ticket to the cookie as data.
HttpCookie authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
if (true == isCookiePersistent)
authCookie.Expires = authTicket.Expiration;
//Add the cookie to the outgoing cookies collection.
Response.Cookies.Add(authCookie);
//You can redirect now.
Response.Redirect(FormsAuthentication.GetRedirectUrl(txtUsername.Text, false));
}
else
{
errorLabel.Text = "Authentication did not succeed. Check user name and password.";
}
}
catch (Exception ex)
{
errorLabel.Text = "Please confirm Username & Password! Password is case sensitive";
}
}
}
}
In Global.asax.cs:
void Application_AuthenticateRequest(object sender, EventArgs e)
{
string cookieName = FormsAuthentication.FormsCookieName;
HttpCookie authCookie = Context.Request.Cookies[cookieName];
if (null == authCookie)
{
//There is no authentication cookie.
return;
}
FormsAuthenticationTicket authTicket = null;
try
{
authTicket = FormsAuthentication.Decrypt(authCookie.Value);
}
catch (Exception ex)
{
//Write the exception to the Event Log.
return;
}
if (null == authTicket)
{
//Cookie failed to decrypt.
return;
}
//When the ticket was created, the UserData property was assigned a
//pipe-delimited string of group names.
string[] groups = authTicket.UserData.Split(new char[] { '|' });
//Create an Identity.
GenericIdentity id = new GenericIdentity(authTicket.Name, "LdapAuthentication");
//This principal flows throughout the request.
GenericPrincipal principal = new GenericPrincipal(id, groups);
Context.User = principal;
}
LdapAuthentication.cs:
using System;
using System.Text;
using System.Collections;
using System.DirectoryServices;
using FormsAuthAd;
using System.Configuration;
namespace FormsAuth
{
public class LdapAuthentication
{
private string _path;
private string _filterAttribute;
private DirectoryEntry entry;
public LdapAuthentication(string path)
{
_path = path;
}
public string getFullName()
{
return _filterAttribute;
}
public bool IsAuthenticated(string domain, string username, string pwd)
{
string domainAndUsername = domain + @"\" + username;
entry = new DirectoryEntry(_path, domainAndUsername, pwd);
try
{
//Bind to the native AdsObject to force authentication.
object obj = entry.NativeObject;
DirectorySearcher search = new DirectorySearcher(entry);
search.Filter = "(SAMAccountName=" + username + ")";
search.PropertiesToLoad.Add("cn");
SearchResult result = search.FindOne();
if (null == result)
{
return false;
}
//Update the new path to the user in the directory.
_path = result.Path;
_filterAttribute = (string)result.Properties["cn"][0];
Constants.Fullname = _filterAttribute;
}
catch (Exception ex)
{
throw new Exception("Error authenticating user. " + ex.Message);
}
return true;
}
public string GetGroups()
{
DirectorySearcher search = new DirectorySearcher(entry);
//DirectoryEntry searchRoot = new DirectoryEntry(_path);
//DirectorySearcher search = new DirectorySearcher(searchRoot);
search.Filter = "(cn=" + _filterAttribute + ")";
search.PropertiesToLoad.Add("memberOf");
StringBuilder groupNames = new StringBuilder();
try
{
SearchResult result = search.FindOne();
int propertyCount = result.Properties["memberOf"].Count;
string dn;
int equalsIndex, commaIndex;
for (int propertyCounter = 0; propertyCounter < propertyCount; propertyCounter++)
{
dn = (string)result.Properties["memberOf"][propertyCounter];
equalsIndex = dn.IndexOf("=", 1);
commaIndex = dn.IndexOf(",", 1);
if (-1 == equalsIndex)
{
return null;
}
groupNames.Append(dn.Substring((equalsIndex + 1), (commaIndex - equalsIndex) - 1));
groupNames.Append("|");
}
}
catch (Exception ex)
{
throw new Exception("Error obtaining group names. " + ex.Message);
}
return groupNames.ToString();
}
}
}
Please let me know if you need any more information.