asp.net集成域账户(C#.net对Active Directory验证) - TOMMYHU - 专注互联网开发及运营技术,提供相关资料及软件下载,奇趣网络时事评论!
Jul 12

最近领导让修改一个asp小系统,由于自己对asp.net比较熟悉而对asp很是陌生!虽然asp的源代码也有,只是修改一下实现CRUD即可,但也是很痛苦的一件事啊!于是一上午都在看代码,郁闷ing.由于公司的电脑都是在域中(Microsoft的外包公司,域名就不说了,估计很多都知道的,哈哈),于是突发奇想,能不能通过AD中用户和密码对系统进行身份验证呢?经过Google总算搜出一篇文章来(还是微软网站上的 http://support.microsoft.com/kb/316748/zh-cn ),按照葫芦画瓢总算是在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配置的几张截图


▲返回顶部
Last modified by tommyhu on2012/07/12 22:01

Add a comment

Nickname

emotemotemotemotemotemotemotemotemotemotemotemotemotemotemotemot