Asp.net读取AD域信息的方法<转>
1、首先新建一个页面(Login.aspx): 前台代码(Login.aspx): <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Login.aspx.cs" Inherits="Login" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>无标题页</title> </head> <body> <form id="Login" method="post" runat="server"> <asp:Label ID="Label1" runat="server" >Domain:</asp:Label> <asp:TextBox ID="txtDomain" runat="server" ></asp:TextBox><br> <asp:Label ID="Label2" runat="server" >Username:</asp:Label> <asp:TextBox ID="txtUsername" runat="server" ></asp:TextBox><br> <asp:Label ID="Label3" runat="server" >Password:</asp:Label> <asp:TextBox ID="txtPassword" runat="server" TextMode=Password></asp:TextBox><br> <asp:Button ID="btnLogin" runat="server" Text="Login" OnClick="Login_Click"></asp:Button><br> <asp:Label ID="errorLabel" runat="server" ForeColor=#ff3300></asp:Label><br> <asp:CheckBox ID="chkPersist" runat="server" Text="Persist Cookie" /> </form> </body> </html> 后台代码(Login.aspx.cs): using System; using System.Data; using System.Configuration; using System.Collections; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; public partial class Login : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } protected void Login_Click(object sender, EventArgs e) { string adPath = "LDAP://" + txtDomain.Text; LdapAuthentication adAuth = new LdapAuthentication(adPath); try { if (true == adAuth.IsAuthenticated(txtDomain.Text, txtUsername.Text, txtPassword.Text)) { string groups = adAuth.GetGroupByUser(); //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 = "Error authenticating. " + ex.Message; } } } 2、在Global.asax里写: 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. System.Security.Principal.GenericIdentity id = new System.Security.Principal.GenericIdentity(authTicket.Name, "LdapAuthentication"); //This principal flows throughout the request. System.Security.Principal.GenericPrincipal principal = new System.Security.Principal.GenericPrincipal(id, groups); Context.User = principal; } 3、在Web.Config里加上: <authentication mode="Forms"> <forms loginUrl="Login.aspx" name="adAuthCookie" timeout="10" path="/"> </forms> </authentication> <authorization> <deny users="?"/> <allow users="*"/> </authorization> <identity impersonate="true"/> 4、再新建一个页面(WebForm1.aspx): 前台代码(WebForm1.aspx): <%@ Page Language="C#" AutoEventWireup="true" CodeFile="WebForm1.aspx.cs" Inherits="WebForm1" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>无标题页</title> </head> <body> <form id="Form1" method="post" runat="server"> <asp:Label ID="lblName" runat="server" /><br/> <asp:Label ID="lblAuthType" runat="server" /> </form> </body> </html> 后台代码(WebForm1.aspx.cs): using System; using System.Data; using System.Configuration; using System.Collections; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; public partial class WebForm1 : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { lblName.Text = "Hello " + Context.User.Identity.Name + "."; lblAuthType.Text = "You were authenticated using " + Context.User.Identity.AuthenticationType + "."; } } 5、再新建一个类(对域的操作主要都要这个类里): LdapAuthentication.cs: using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; using System.DirectoryServices; using System.Text; /// <summary> /// LdapAuthentication 的摘要说明 /// </summary> public class LdapAuthentication { public LdapAuthentication() { } private string _path; private string _filterAttribute; public LdapAuthentication(string path) { _path = path; } /// <summary> /// 判断是否域用户 /// </summary> /// <param name="domain">域名</param> /// <param name="username">用户名</param> /// <param name="pwd">密码</param> /// <returns></returns> public bool IsAuthenticated(string domain, string username, string pwd) { string domainAndUsername = domain + @"\" + username; DirectoryEntry 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]; } catch (Exception ex) { throw new Exception("Error authenticating user. " + ex.Message); } return true; } /// <summary> /// 根据用户名获取所属组名 /// </summary> /// <returns></returns> public string GetGroupByUser() { DirectorySearcher search = new DirectorySearcher(_path); 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)); } } catch (Exception ex) { throw new Exception("Error obtaining group names. " + ex.Message); } return groupNames.ToString(); } /// <summary> /// 获取组用户 /// </summary> /// <param name="Groupname">组名</param> /// <returns></returns> public string[] GetUsersForGroup(string Groupname) { DirectorySearcher ds = new DirectorySearcher(_path); ds.Filter = "(&(objectClass=group)(cn=" + Groupname + "))"; ds.PropertiesToLoad.Add("member"); SearchResult r = ds.FindOne(); if (r.Properties["member"] == null) { return (null); } string[] results = new string[r.Properties["member"].Count]; for (int i = 0; i < r.Properties["member"].Count; i++) { string theGroupPath = r.Properties["member"][i].ToString(); results[i] = theGroupPath.Substring(3, theGroupPath.IndexOf(",") - 3); } return (results); } /// <summary> /// 获取用户所属组 /// </summary> /// <param name="username">用户名</param> /// <returns></returns> public string[] GetGroupsForUser(string username) { DirectorySearcher ds = new DirectorySearcher(_path); ds.Filter = "(&(sAMAccountName=" + username + "))"; ds.PropertiesToLoad.Add("memberof"); SearchResult r = ds.FindOne(); if (r.Properties["memberof"].Count == 0) { return (null); } string[] results = new string[r.Properties["memberof"].Count]; for (int i = 0; i < r.Properties["memberof"].Count; i++) { string theGroupPath = r.Properties["memberof"][i].ToString(); results[i] = theGroupPath.Substring(3, theGroupPath.IndexOf(",") - 3); } return (results); } public string[] GetAllGroupsForUser(string username) { DirectorySearcher ds = new DirectorySearcher(_path); ds.Filter = "(&(sAMAccountName=" + username + "))"; ds.PropertiesToLoad.Add("memberof"); SearchResult r = ds.FindOne(); if (r.Properties["memberof"] == null) { return (null); } string[] results = new string[r.Properties["memberof"].Count + 1]; for (int i = 0; i < r.Properties["memberof"].Count; i++) { string theGroupPath = r.Properties["memberof"][i].ToString(); results[i] = theGroupPath.Substring(3, theGroupPath.IndexOf(",") - 3); } results[r.Properties["memberof"].Count] = "All";//All组属于任何人,在AD之外定义了一个组,以便分配用户权限 return (results); } /// <summary> /// 获取组用户 /// </summary> /// <param name="username">用户名</param> /// <returns></returns> public string GetUserDisplayName(string username) { string results; DirectorySearcher ds = new DirectorySearcher(_path); ds.Filter = "(&(objectClass=user)(sAMAccountName=" + username + "))"; ds.PropertiesToLoad.Add("DisplayName"); SearchResult r = ds.FindOne(); results = r.GetDirectoryEntry().InvokeGet("DisplayName").ToString(); return (results); } public string GetAdGroupDescription(string prefix)//根据CN获取组description { string results; DirectorySearcher groupsDS = new DirectorySearcher(_path); groupsDS.Filter = "(&(objectClass=group)(CN=" + prefix + "*))"; groupsDS.PropertiesToLoad.Add("cn"); SearchResult sr = groupsDS.FindOne(); results = sr.GetDirectoryEntry().InvokeGet("description").ToString(); return (results); } public DataTable GetAdGroupInfo()//根据CN获取组信息 { DataTable dt = new DataTable(); dt.Columns.Add("URL", typeof(System.String)); dt.Columns.Add("cn", typeof(System.String)); dt.Columns.Add("Description", typeof(System.String)); DirectorySearcher searcher = new DirectorySearcher(_path); searcher.Filter = "(&(objectClass=group))"; //searcher.SearchScope = SearchScope.Subtree; //searcher.Sort = new SortOption("description", System.DirectoryServices.SortDirection.Ascending); searcher.PropertiesToLoad.AddRange(new string[] { "cn", "description" }); SearchResultCollection results = searcher.FindAll(); if (results.Count == 0) { return (null); } else { foreach (SearchResult result in results) { DataRow dr = dt.NewRow(); dr[0] = result.Path.ToString(); dr[1] = result.GetDirectoryEntry().InvokeGet("cn").ToString(); if (result.GetDirectoryEntry().InvokeGet("Description") != null) dr[2] = result.GetDirectoryEntry().InvokeGet("Description").ToString(); else dr[2] = result.GetDirectoryEntry().InvokeGet("cn").ToString(); dt.Rows.Add(dr); } dt.DefaultView.Sort = "description ASC"; return dt; } } public string getAccountName(string cn) //根据CN获取登陆名 { foreach (string path in _path.Split(',')) { DirectorySearcher ds = new DirectorySearcher(path); ds.Filter = "(&(objectClass=user)(cn=*" + cn + "*))"; ds.PropertiesToLoad.Add("sAMAccountName"); SearchResult r = ds.FindOne(); if (r != null) return r.GetDirectoryEntry().InvokeGet("sAMAccountName").ToString(); } return null; } public DataTable adUserlist(string groupname) //生成用户数据表 { DataTable dt = new DataTable(); dt.Columns.Add("cn", typeof(System.String)); dt.Columns.Add("sAMAccountName", typeof(System.String)); string[] groupmember = GetUsersForGroup(groupname); if (groupmember.Length == 0) { return null; } else { foreach (string member in groupmember) { if (IsAccountActive(getAccountControl(getAccountName(member)))) { DataRow dr = dt.NewRow(); dr[0] = member.ToString(); dr[1] = getAccountName(member); dt.Rows.Add(dr); } } return dt; } } public DataTable adUserlist() //生成指定的用户信息数据表 { DataTable dt = new DataTable(); dt.Columns.Add("memberof", typeof(System.String)); dt.Columns.Add("cn", typeof(System.String)); dt.Columns.Add("Description", typeof(System.String)); dt.Columns.Add("name", typeof(System.String)); dt.Columns.Add("Mail", typeof(System.String)); dt.Columns.Add("samaccountname", typeof(System.String)); dt.Columns.Add("whencreated", typeof(System.String)); dt.Columns.Add("title", typeof(System.String)); dt.Columns.Add("department", typeof(System.String)); DirectorySearcher searcher = new DirectorySearcher(_path); //searcher.Filter = "(description=ADPJ*)"; searcher.Filter = "(description=ADPL*)"; searcher.PropertiesToLoad.AddRange(new string[] { "memberof", "cn", "description", "name", "Mail", "samaccountname", "whencreated", "title", "department"}); SearchResultCollection results = searcher.FindAll(); if (results.Count == 0) { return (null); } else { foreach (SearchResult result in results) { DataRow dr = dt.NewRow(); //dr[0] = result.Path.ToString(); if (result.GetDirectoryEntry().InvokeGet("memberof") != null) dr[0] = result.GetDirectoryEntry().InvokeGet("memberof").ToString(); else dr[0] = ""; if (result.GetDirectoryEntry().InvokeGet("cn") != null) dr[1] = result.GetDirectoryEntry().InvokeGet("cn").ToString(); else dr[1] = ""; if (result.GetDirectoryEntry().InvokeGet("Description") != null) dr[2] = result.GetDirectoryEntry().InvokeGet("Description").ToString(); else dr[2] = result.GetDirectoryEntry().InvokeGet("cn").ToString(); if (result.GetDirectoryEntry().InvokeGet("name") != null) dr[3] = result.GetDirectoryEntry().InvokeGet("name").ToString(); else dr[3] = ""; if (result.GetDirectoryEntry().InvokeGet("Mail") != null) dr[4] = result.GetDirectoryEntry().InvokeGet("Mail").ToString(); else dr[4] = ""; if (result.GetDirectoryEntry().InvokeGet("samaccountname") != null) dr[5] = result.GetDirectoryEntry().Properties["samaccountname"].Value.ToString(); else dr[5] = ""; if (result.GetDirectoryEntry().InvokeGet("whencreated") != null) dr[6] = result.GetDirectoryEntry().Properties["whencreated"].Value.ToString(); else dr[6] = ""; if (result.GetDirectoryEntry().InvokeGet("title") != null) dr[7] = result.GetDirectoryEntry().Properties["title"].Value.ToString(); else dr[7] = ""; if (result.GetDirectoryEntry().InvokeGet("department") != null) dr[8] = result.GetDirectoryEntry().Properties["department"].Value.ToString(); else dr[8] = ""; dt.Rows.Add(dr); } dt.DefaultView.Sort = "description ASC"; return dt; } } public void adUserlistbox(ListBox results, string groupName) //生成USER { results.Items.Clear(); DataTable dt = adUserlist(groupName); if (dt != null) { results.DataSource = dt; results.DataTextField = dt.Columns[0].Caption; results.DataValueField = dt.Columns[1].Caption; results.DataBind(); } } public void adGrouplistbox(ListBox results) { results.Items.Clear(); DataTable dt = GetAdGroupInfo(); DataRow dr = dt.NewRow(); dr[1] = "All"; dr[2] = "All"; dt.Rows.Add(dr); results.DataSource = dt; results.DataTextField = dt.Columns[2].Caption; results.DataValueField = dt.Columns[1].Caption; results.DataBind(); } public void aduserGrouplist(DropDownList results) { results.Items.Clear(); DataTable dt = GetAdGroupInfo(); results.DataSource = dt; results.DataTextField = dt.Columns[2].Caption; results.DataValueField = dt.Columns[1].Caption; results.DataBind(); } public int getAccountControl(string accountName)//获取权限码 { int results; DirectorySearcher ds = new DirectorySearcher(_path); ds.Filter = "(&(objectClass=user)(sAMAccountName=" + accountName + "))"; ds.PropertiesToLoad.Add("userAccountControl"); try { SearchResult r = ds.FindOne(); results = Convert.ToInt32(r.GetDirectoryEntry().InvokeGet("userAccountControl")); return results; } catch { return 0; } } public bool IsAccountActive(int userAccountControl)//判断是否有效 { int ADS_UF_ACCOUNTDISABLE = 0X0002; int userAccountControl_Disabled = Convert.ToInt32(ADS_UF_ACCOUNTDISABLE); int flagExists = userAccountControl & userAccountControl_Disabled; if (flagExists > 0) return false; else return true; } public DirectoryEntry GetDirectoryEntryByAccount(string sAMAccountName) { DirectorySearcher deSearch = new DirectorySearcher(_path); deSearch.Filter = "(&(objectCategory=person)(objectClass=user)(sAMAccountName=" + sAMAccountName + "))"; // deSearch.SearchScope = SearchScope.Subtree; try { SearchResult result = deSearch.FindOne(); if (result == null) { return null; } DirectoryEntry de = new DirectoryEntry(_path); return de; } catch { //throw; return null; } } } 另外增加一个读取用户信息的方法: /// <summary> /// 读取AD用户信息 /// </summary> /// <param name= "ADUsername "> 用户 </param> /// <param name= "ADPassword "> 密码 </param> /// <param name= "domain "> 域名 </param> /// <returns> </returns> public System.Collections.SortedList AdUserInfo(string ADUsername, string ADPassword, string domain) { System.DirectoryServices.DirectorySearcher src; string ADPath = "LDAP:// " + domain;// "ou=总公司,DC=abc,DC=com,DC=cn "; + ",ou=总公司 " System.Collections.SortedList sl = new System.Collections.SortedList(); string domainAndUsername = domain + @"\" + ADUsername; System.DirectoryServices.DirectoryEntry de = new System.DirectoryServices.DirectoryEntry(ADPath, domainAndUsername, ADPassword); src = new System.DirectoryServices.DirectorySearcher(de); src.Filter = "(SAMAccountName=" + ADUsername + ")"; src.PageSize = 10000;// 此参数可以任意设置,但不能不设置,如不设置读取AD数据为0~999条数据,设置后可以读取大于1000条数据。 // src.SizeLimit = 2000; src.SearchScope = System.DirectoryServices.SearchScope.Subtree; try { foreach (System.DirectoryServices.SearchResult res in src.FindAll()) { sl.Add(res.GetDirectoryEntry().Properties["Name"].Value, res.GetDirectoryEntry().InvokeGet("Description")); } } catch (Exception ex) { throw new Exception("Get Ad Info ", ex); } return sl; } 下面列举一些域中存在的属性: distinguishedname;objectclass;pwdlastset;userprincipalname与mail一样;memberof;objectguid;instancetype;codepage;whenchanged;samaccountname;cn;usncreated;sn(姓);accountexpires;usnchanged;displayname;description;useraccountcontrol(权限码);whencreated;givenName(名);samaccounttype;objectcategory;countrycode;primarygroupid;objectsid;title(职务);department(部门) 备注: 1. 在ASP.NET中专用属性: 获取服务器电脑名:Page.Server.ManchineName 获取用户信息:Page.User 获取客户端电脑名:Page.Request.UserHostName 获取客户端电脑IP:Page.Request.UserHostAddress 2. 在网络编程中的通用方法: 获取当前电脑名:static System.Net.Dns.GetHostName() 根据电脑名取出全部IP地址:static System.Net.Dns.Resolve(电脑名).AddressList 也可根据IP地址取出电脑名:static System.Net.Dns.Resolve(IP地址).HostName 3. 系统环境类的通用属性: 当前电脑名:static System.Environment.MachineName 当前电脑所属网域:static System.Environment.UserDomainName 当前电脑用户:static System.Environment.UserName 添加域用户操作可参考:http://www.cnblogs.com/qintm/articles/1338665.html
原文地址:http://world-20.blog.163.com/blog/static/43382284201011424211679/