通过一个示例,展开对下面几点知识的学习
示例:从ASP .NET 进行 Active Directory 域服务身份验证
http://msdn.microsoft.com/zh-cn/library/ms180890
(1)域的配置
资料出处:http://wenku.baidu.com/view/a0746d37b90d6c85ec3ac66e.html
(2)深入了解
Windows_Server_2008_R2_AD_DS架构(没看明白)
(3)ASP.NETWeb 应用程序安全性
资料出处:http://msdn.microsoft.com/zh-cn/library/330a99hc(v=vs.100).aspx
(4)System.DirectoryServices命名空间, DirectoryEntry类和DirectorySearcher类,
System.Security.Principal.GenericPrincipal,System.Web.Security.FormsAuthentication
资料出处:http://msdn.microsoft.com/zh-cn/library/System.DirectoryServices(v=vs.80).aspx
(5)LDAP(轻量目录访问协议)
AD:Active Directory
林、域树、域关系:域属于域树,域树属于域林。当创建第一个域的时候,其实是创建了一林,包含一个域树,域树包含一个域。域提供的是管理功能类似于数据库。
示例准备——创建域(结合资料1):
1.创建DNS服务器——为域中的计算机提供域名解析服务,域中的计算机利用DNS提供的SRV记录定位域控制器。创建区域。
2.创建域控制器——域控制器中存储着AD,在TCP/IP中设置首选DNS服务器地址为第一步创建的DNS服务器的IP。运行—>Dcpromo创建域控制器,其实为安装一个AD数据库。要注意域名中的.com。
3.创建计算机账号——首先把要加入域的计算机DNS服务器地址改成域的DNS服务器地址。系统属性—计算机名—更改加入域,输入有权限创建账号的用户名密码。
4.创建用户账号——在域控制器中打开AD用户和计算机,创建组织单位,创建用户。组织单位包括组或直接包括用户,组包括用户。一个用户可以存在多个组内,但只能存在于一个组织单位中。
FormsAuthAd项目
LdapAuthentication.cs
using System;
using System.Text;
using System.Collections;
using System.Web.Security;
using System.Security.Principal;
using System.DirectoryServices;
using System.Collections.Generic;
namespace FormsAuth
{
public class LdapAuthentication
{
private string _path;
private string _filterAttribute;
//全局DirectoryEntry变量
DirectoryEntry ou = new DirectoryEntry();
public LdapAuthentication(string path)
{
_path = path;
}
public LdapAuthentication()
{
}
public bool IsAuthenticated(string domain, string username, string pwd)
{
string domainAndUsername = domain + @"\" + username;
DirectoryEntry entry = new DirectoryEntry(_path, domainAndUsername, pwd);
//给全局变量赋值
ou = 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;
}
public string GetGroups(string Domain, string Username, string Password)
{
string domainAndUsername = Domain + @"\" + Username;
DirectoryEntry entry = new DirectoryEntry(_path, domainAndUsername, Password);
DirectorySearcher search = new DirectorySearcher(entry);
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();
}
//根据登陆用户的父节点的父节点得到所有部门
public List<string> GetOU()
{
List<string> lst = new List<string>();
try
{
object obj = ou.NativeObject;
DirectorySearcher searcher = new DirectorySearcher(ou);
searcher.Filter = "(objectClass=organizationalUnit)";
searcher.PropertiesToLoad.Add("ou");
SearchResultCollection ret = searcher.FindAll();
foreach (SearchResult sr in ret)
{
if (sr != null)
{
lst.Add(sr.Properties["ou"][0].ToString());
}
}
}
catch (System.Exception ex)
{
}
return lst;
}
//根据部门名称返回所有该部门用户
public List<string> GetUsers(string ouName)
{
List<string> lst = new List<string>();
try
{
object obj = ou.NativeObject;
DirectorySearcher searcher = new DirectorySearcher(ou);
searcher.Filter = "(&(objectClass=organizationalUnit)(ou=" + ouName + "))";
searcher.PropertiesToLoad.Add("cn");
SearchResultCollection ret = searcher.FindAll();
foreach (SearchResult sr in ret)
{
if (sr != null)
{
lst.Add(sr.Properties["cn"][0].ToString());
}
}
}
catch (System.Exception ex)
{
}
return lst;
}
}
}
Global.asax.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.SessionState;
using System.Web.Security;
using System.Security.Principal;
namespace FormsAuthAd
{
public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
}
protected void Session_Start(object sender, EventArgs e)
{
}
protected void Application_BeginRequest(object sender, EventArgs e)
{
}
protected 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;
Response.Write("Groups: " + authTicket.UserData + "<br>");
}
protected void Application_Error(object sender, EventArgs e)
{
}
protected void Session_End(object sender, EventArgs e)
{
}
protected void Application_End(object sender, EventArgs e)
{
}
}
}
Logon.aspx
<%@ Page language="c#" AutoEventWireup="true" %>
<%@ Import Namespace="FormsAuth" %>
<html>
<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>
<script runat=server>
void Login_Click(object sender, EventArgs e)
{
string adPath = "LDAP://" + txtDomain.Text.ToString();
LdapAuthentication adAuth = new LdapAuthentication(adPath);
try
{
if(true == adAuth.IsAuthenticated(txtDomain.Text, txtUsername.Text, txtPassword.Text))
{
string groups = adAuth.GetGroups(txtDomain.Text, txtUsername.Text, txtPassword.Text);
string userName = txtUsername.Text.ToString();
//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);
List<string> lstUsers = adAuth.GetOU();
Session["list"] = lstUsers;
//You can redirect now.
Response.Redirect(FormsAuthentication.GetRedirectUrl(userName, false));
}
else
{
errorLabel.Text = "Authentication did not succeed. Check user name and password.";
}
}
catch(Exception ex)
{
errorLabel.Text = "Error authenticating. " + ex.Message;
}
}
</script>
Default.aspx.cs
<%@ Page language="c#" AutoEventWireup="true" %>
<%@ Import Namespace="System.Security.Principal" %>
<html>
<body>
<form id="Form1" method="post" runat="server">
<asp:Label ID="lblName" Runat=server /><br>
<asp:Label ID="lblAuthType" Runat=server />
</form>
</body>
</html>
<script runat=server>
void Page_Load(object sender, EventArgs e)
{
lblName.Text = "Hello " + Context.User.Identity.Name + ".";
lblAuthType.Text = "You were authenticated using " + Context.User.Identity.AuthenticationType + ".";
}
</script>
web.config
//
<?xml version="1.0"?>
<configuration>
<system.web>
//这里是此项目的关键配置
<authentication mode="Forms">
<forms loginUrl="logon.aspx" name="adAuthCookie" timeout="10" path="/"/>
</authentication>
<authorization>
<deny users="?"/>
<allow users="*"/>
</authorization>
<identity impersonate="true" />
</system.web>
</configuration>
待续,小弟初学编程,希望通过日记方式总结每日所学,望路过的各位大神给予指导与建议,找出错误与不足之处,小弟不胜感激,2013-08-01