Asp.net集成Windows域账户登陆
-
![]()
Code
1
using System;
2
using System.Text;
3
using System.Collections;
4
using System.DirectoryServices;
5![]()
6
namespace 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
![]()
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
}
![]()
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
![]()
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
1
protected 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
}
最近领导让修改一个asp小系统,由于自己对asp.net比较熟悉而对asp很是陌生!虽然asp的源代码也有,只是修改一下实现CRUD即可,但也是很痛苦的一件事啊!于是一上午都在看代码,郁闷ing.由于公司的电脑都是在域中(Microsoft的外包公司,域名就不说了,估计很多都知道的,哈哈),于是突发奇想,能不能通过AD中用户和密码对系统进行身份验证呢?经过Google总算搜出一篇文章来(还是微软网站上的,URL),按照葫芦画瓢总算是在VS2008中调试成功了!顺便分享一下算是自己的经验吧!
1. 创建Web Site,添加一个类,代码如下
1
using System;2
using System.Text;3
using System.Collections;4
using System.DirectoryServices;5

6
namespace FormsAuth7


{8
public class LdapAuthentication9

{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
try24

{ //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
try58

{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方法,代码如下
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
try14

{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 a29
//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,代码如下
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访问权限的用户!IIS6和IIS7设置步骤有点不同可以参考下面的图片!
创建Logon.aspx来进行测试了啊,代码伺候!
HTML 代码
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>
1
protected void Login_Click(object sender, EventArgs e)2

{3
String adPath = "LDAP://Here is the full domain name"; //Fully-qualified Domain Name4
LdapAuthentication adAuth = new LdapAuthentication(adPath);5
try6

{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
else32

{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配置的几张截图



浙公网安备 33010602011771号