Asp.net集成Windows域賬戶登陸

 
-

最近領導讓修改一個asp小系統,由於自己對asp.net比較熟悉而對asp很是陌生!雖然asp的源代碼也有,只是修改一下實現CRUD即可,但也是很痛苦的一件事啊!於是一上午都在看代碼,鬱悶ing.由於公司的電腦都是在域中(Microsoft的外包公司,域名就不說了,估計很多都知道的,哈哈),於是突發奇想,能不能通過AD中用戶和密碼對系統進行身份驗證呢?經過Google總算搜出一篇文章來(還是微軟網站上的,URL),按照葫蘆畫瓢總算是在VS2008中調試成功了!順便分享一下算是自己的經驗吧!

1.       創建Web Site,添加一個類,代碼如下

 

Code
 1using System;
 2using System.Text;
 3using System.Collections;
 4using System.DirectoryServices;
 5
 6namespace FormsAuth
 7{
 8    public class LdapAuthentication
 9    {
10        private String _path;
11        private String _filterAttribute;
12
13        public LdapAuthentication(String path)
14        {
15            _path = path;
16        }
17
18        public bool IsAuthenticated(String domain, String username, String pwd)
19        {
20            String domainAndUsername = domain + @"\" + username;
21            DirectoryEntry entry = new DirectoryEntry(_path, domainAndUsername, pwd);
22
23            try
24            {    //Bind to the native AdsObject to force authentication.            
25                Object obj = entry.NativeObject;
26
27                DirectorySearcher search = new DirectorySearcher(entry);
28
29                search.Filter = "(SAMAccountName=" + username + ")";
30                search.PropertiesToLoad.Add("cn");
31                SearchResult result = search.FindOne();
32
33                if (null == result)
34                {
35                    return false;
36                }
37
38                //Update the new path to the user in the directory.
39                _path = result.Path;
40                _filterAttribute = (String)result.Properties["cn"][0];
41            }
42            catch (Exception ex)
43            {
44                throw new Exception("Error authenticating user. " + ex.Message);
45            }
46
47            return true;
48        }
49
50        public String GetGroups()
51        {
52            DirectorySearcher search = new DirectorySearcher(_path);
53            search.Filter = "(cn=" + _filterAttribute + ")";
54            search.PropertiesToLoad.Add("memberOf");
55            StringBuilder groupNames = new StringBuilder();
56
57            try
58            {
59                SearchResult result = search.FindOne();
60
61                int propertyCount = result.Properties["memberOf"].Count;
62
63                String dn;
64                int equalsIndex, commaIndex;
65
66                for (int propertyCounter = 0; propertyCounter < propertyCount; propertyCounter++)
67                {
68                    dn = (String)result.Properties["memberOf"][propertyCounter];
69
70                    equalsIndex = dn.IndexOf("=", 1);
71                    commaIndex = dn.IndexOf(",", 1);
72                    if (-1 == equalsIndex)
73                    {
74                        return null;
75                    }
76
77                    groupNames.Append(dn.Substring((equalsIndex + 1), (commaIndex - equalsIndex) - 1));
78                    groupNames.Append("|");
79
80                }
81            }
82            catch (Exception ex)
83            {
84                throw new Exception("Error obtaining group names. " + ex.Message);
85            }
86            return groupNames.ToString();
87        }
88    }
89}
90

 

2.       修改Global.ascx文件增加Application_AuthenticateRequest方法,代碼如下

 

Code
 1 void Application_AuthenticateRequest(Object sender, EventArgs e)
 2    {
 3        String cookieName = FormsAuthentication.FormsCookieName;
 4        HttpCookie authCookie = Context.Request.Cookies[cookieName];
 5
 6        if (null == authCookie)
 7        {//There is no authentication cookie.
 8            return;
 9        }
10
11        FormsAuthenticationTicket authTicket = null;
12
13        try
14        {
15            authTicket = FormsAuthentication.Decrypt(authCookie.Value);
16        }
17        catch (Exception)
18        {
19            //Write the exception to the Event Log.
20            return;
21        }
22
23        if (null == authTicket)
24        {//Cookie failed to decrypt.
25            return;
26        }
27
28        //When the ticket was created, the UserData property was assigned a
29        //pipe-delimited string of group names.
30        String[] groups = authTicket.UserData.Split(new char[] { '|' });
31
32        //Create an Identity.
33        System.Security.Principal.GenericIdentity id = new GenericIdentity(authTicket.Name, "LdapAuthentication");
34
35        //This principal flows throughout the request.
36        GenericPrincipal principal = new GenericPrincipal(id, groups);
37
38        Context.User = principal;
39
40    }

 

3.       修改Web.config,代碼如下

 

Code
 1<system.web>
 2    <authentication mode="Forms">
 3      <forms loginUrl="logon.aspx" name="adAuthCookie" timeout="10" path="/" >
 4      </forms>
 5    </authentication> 
 6    <authorization> 
 7      <deny users="?" />
 8      <allow users="*" />
 9    </authorization> 
10    <identity impersonate="true" />
11  </system.web>
12


 

4.       爲匿名身份驗證配置IIS
默認網站——虛擬目錄——目錄安全——匿名訪問和身份驗證——編輯——去掉默認的IUSER賬戶,IUSER 默認狀態下沒有訪問AD的權限,因此需要替換成一個具有AD訪問權限的用戶!IIS6IIS7設置步驟有點不同可以參考下面的圖片!

創建Logon.aspx來進行測試了啊,代碼伺候!
HTML 代碼

 

 

Code
 1<form id="Login" method="post" runat="server">
 2    Your Domain information is:<asp:Label runat="server" ID="Domainname"></asp:Label>
 3   <br />
 4      <asp:Label ID="Label1" Runat=server >Domain:</asp:Label>
 5      <asp:TextBox ID="txtDomain" Runat=server ></asp:TextBox><br>    
 6      <asp:Label ID="Label2" Runat=server >Username:</asp:Label>
 7      <asp:TextBox ID=txtUsername Runat=server ></asp:TextBox><br>
 8      <asp:Label ID="Label3" Runat=server >Password:</asp:Label>
 9      <asp:TextBox ID="txtPassword" Runat=server TextMode=Password></asp:TextBox><br>
10      <asp:Button ID="btnLogin" Runat=server Text="Login" OnClick="Login_Click"></asp:Button><br>
11      <asp:Label ID="errorLabel" Runat=server ForeColor=#ff3300></asp:Label><br>
12      <asp:CheckBox ID=chkPersist Runat=server Text="Persist Cookie" />
13    </form>

 

 

Code
 1protected void Login_Click(object sender, EventArgs e)
 2    {
 3        String adPath = "LDAP://Here is the full domain name"; //Fully-qualified Domain Name
 4        LdapAuthentication adAuth = new LdapAuthentication(adPath);
 5        try
 6        {
 7            if (true == adAuth.IsAuthenticated(txtDomain.Text, txtUsername.Text, txtPassword.Text))
 8            {
 9                String groups = adAuth.GetGroups();
10
11                //Create the ticket, and add the groups.
12                bool isCookiePersistent = chkPersist.Checked;
13                FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(1, txtUsername.Text,
14              DateTime.Now, DateTime.Now.AddMinutes(60), isCookiePersistent, groups);
15
16                //Encrypt the ticket.
17                String encryptedTicket = FormsAuthentication.Encrypt(authTicket);
18
19                //Create a cookie, and then add the encrypted ticket to the cookie as data.
20                HttpCookie authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
21
22                if (true == isCookiePersistent)
23                    authCookie.Expires = authTicket.Expiration;
24
25                //Add the cookie to the outgoing cookies collection.
26                Response.Cookies.Add(authCookie);
27
28                //You can redirect now.
29                Response.Redirect(FormsAuthentication.GetRedirectUrl(txtUsername.Text, false));
30            }
31            else
32            {
33                errorLabel.Text = "Authentication did not succeed. Check user name and password.";
34            }
35        }
36        catch (Exception ex)
37        {
38           errorLabel.Text = "Error authenticating. " + ex.Message;
39        }
40
41    }

 

 由於上面設計比較多的代碼,沒有貼出圖片,下面就是IIS6和IIS7配置的幾張截圖

 

發佈了0 篇原創文章 · 獲贊 1 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章