如何开发一个帮助程序类,以便在所有基于 Web 的应用程序中使用,以从 Active Directory 中检索信息
本文关键字:应用程序 Web 以从 检索 信息 Directory Active 开发 何开发 一个 帮助程序 | 更新日期: 2023-09-27 18:33:56
我是一个新的Web开发人员,在我的公司中,所有 ASP.NET 应用程序都依赖于一个系统,该系统从SAP系统中提取用户信息并将其检索为XML文档。该系统只有一个文本框,用于插入用户名以检索其信息。一个例子:如果插入用户名:johnA系统将为您提供以下信息:John阿内森埃利等等。
然后,在基于 Web ASP.NET 应用程序中,我们过去使用三个 C# 类来建立与此系统的连接,并帮助从该系统获取特定的用户信息。无论如何,现在我们想用一个从活动目录获取用户信息的新系统替换该系统。
我将以下代码放入服务器中,它运行良好,因此当员工在我们的服务器中转到此代码时,他将看到一个显示其所有信息的页面。我现在想做的是在我们所有开发和下一个新开发的基于 Web 的应用程序中使用它,方法是放置一个文本框来放置用户的用户名并从该系统检索他的所有信息。那么该怎么做呢?
我是初学者,我无法在Google或其他任何地方找到执行此操作的方法。
我访问活动目录的类的代码是:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.DirectoryServices;
/// <summary>
/// Summary description for ActiveDirectory
/// </summary>
public class ActiveDirectory
{
public static string GetPersonData(string id, string datatype)
{
//return "x xx xxxx xxx xxx"; //comment this line.
//Faster performance through Active Directory
string property = datatype;
switch (property) //backwards compatibility
{
/* case "tel":
return FindProperty(id, Property.Tel);*/
case "name":
return FindProperty(id, Property.Name);
case "dept":
return FindProperty(id, Property.Dept);
case "line":
return FindProperty(id, Property.Line);
case "email":
return FindProperty(id, Property.Email);
case "id":
return FindProperty(id, Property.Name);
default:
return "";
}
}
//ACTIVE DIRECTORY OPTION.. FOR A BETTER PERFORMANCE
const string ID = "cn";
const string NAME = "displayName";
const string TEL = "telephoneNumber";
const string DEPT = "department";
const string LINE = "extensionAttribute3";
const string UNIT = "extensionAttribute10";
const string TITLE = "title";
const string FNAME = "givenName";
const string MNAME = "initials";
const string LNAME = "sn";
const string EMAIL = "mail";
const string AREA = "extensionAttribute3";
const string MANAGER = "manager";
const string ORGCODE = "extensionAttribute10";
const string DN = "distinguishedName";
public enum Property
{
Name, Tel, Dept, Line, Unit, Title, Fname, Mname, Lname, Email, Manager, OrgCode, DistinguishedName
}
public static DirectoryEntry GetDirectoryEntry()
{
using (((System.Security.Principal.WindowsIdentity)HttpContext.Current.User.Identity).Impersonate())
{
DirectoryEntry de = new DirectoryEntry(); //DirectoryEntry class encapsulates a node or object in the AD hierarchy
de.Path = "LDAP://CompanyName.COM";
de.AuthenticationType = AuthenticationTypes.Delegation;
return de;
}
}
public static bool UserExists(string username)
{
DirectoryEntry de = GetDirectoryEntry();
DirectorySearcher deSearch = new DirectorySearcher(); //Directory Searcher: It will perform queries against the active directory hierarchy
deSearch.SearchRoot = de; //SearchRoot is used to specify where the search starts
deSearch.Filter = "(&(objectClass=user) (cn=" + username + "))"; //the search retrieves all objects.
// Create a SearchResultCollection object to hold a collection of SearchResults
// returned by the FindAll method.
SearchResultCollection results = deSearch.FindAll();
return results.Count > 0;
}
public static String FindName(String userAccount)
{
DirectoryEntry entry = GetDirectoryEntry();
String account = userAccount.Replace(@"Domain'", "");
try
{
DirectorySearcher search = new DirectorySearcher(entry);
search.Filter = "(SAMAccountName=" + account + ")";
search.PropertiesToLoad.Add("displayName");
SearchResult result = search.FindOne();
if (result != null)
{
return result.Properties["displayname"][0].ToString();
}
else
{
return "Unknown User";
}
}
catch (Exception ex)
{
string debug = ex.Message;
return debug;
}
}
public static String FindProperty(String userAccount, Property p)
{
string property = "";
//proceed with LDAP search.
switch (p)
{
case Property.Dept:
property = DEPT;
break;
case Property.Email:
property = EMAIL;
break;
case Property.Fname:
property = FNAME;
break;
case Property.Line:
property = LINE;
break;
case Property.Lname:
property = LNAME;
break;
case Property.Mname:
property = MNAME;
break;
case Property.Name:
property = NAME;
break;
case Property.Tel:
property = TEL;
break;
case Property.Title:
property = TITLE;
break;
case Property.Unit:
property = UNIT;
break;
case Property.Manager:
property = MANAGER;
break;
case Property.OrgCode:
property = ORGCODE;
break;
case Property.DistinguishedName:
property = DN;
break;
default:
return "";
}
DirectoryEntry entry = GetDirectoryEntry();
String account = userAccount.Replace(@"Domain'", "");
try
{
System.Text.Encoding enc = System.Text.Encoding.ASCII;
DirectorySearcher search = new DirectorySearcher(entry);
search.Filter = "(&(objectCategory=user)(SAMAccountName=" + account + "))";
search.PropertiesToLoad.Add(property);
SearchResult result = search.FindOne();
search.Dispose();
entry.Close();
entry.Dispose();
if (result != null)
{
object value = result.Properties[property][0];
if (value is System.Byte[])
return enc.GetString((byte[])value);
else
return value.ToString();
}
else
{
return "-";
}
}
catch (Exception ex)
{
string debug = ex.Message;
return "debug";
}
}
public static List<string> FindChildren(string userAccount)
{
DirectoryEntry entry = GetDirectoryEntry();
String account = userAccount.Replace(@"Domain'", "");
string dn = FindProperty(userAccount, Property.DistinguishedName);
dn.Replace("*","''2a");
dn.Replace("(", "''28");
dn.Replace(")", "''29");
dn.Replace("''", "''5c");
dn.Replace("NUL", "''00");
dn.Replace("/", "''2f");
string property = ID;
List<string> output = new List<string>();
try
{
System.Text.Encoding enc = System.Text.Encoding.ASCII;
DirectorySearcher search = new DirectorySearcher(entry);
search.Filter = "(&(objectCategory=user)(manager=" + dn + "))";
search.PropertiesToLoad.Add(property);
SearchResultCollection results = search.FindAll();
search.Dispose();
entry.Close();
entry.Dispose();
if (results != null)
{
foreach (SearchResult result in results)
{
object value = result.Properties[property][0];
if (value is System.Byte[])
output.Add(enc.GetString((byte[])value));
else
output.Add(value.ToString());
}
}
}
catch (Exception ex)
{
throw ex;
}
return output;
}
public static string FindOrg(string orgcode, string property)
{
DirectoryEntry entry = GetDirectoryEntry();
try
{
System.Text.Encoding enc = System.Text.Encoding.ASCII;
DirectorySearcher search = new DirectorySearcher(entry);
search.Filter = "(&(objectCategory=user)(" + ORGCODE + "=" + orgcode + "*))";
search.PropertiesToLoad.Add(property);
SearchResult result = search.FindOne();
search.Dispose();
entry.Close();
entry.Dispose();
if (result != null)
{
object value = result.Properties[property][0];
if (value is System.Byte[])
return enc.GetString((byte[])value);
else
return value.ToString();
}
else
{
return "-";
}
}
catch (Exception ex)
{
string debug = ex.Message;
return "debug";
}
}
}
更新:
供您参考,上述类位于服务器上。现在,我正在开发一个新的基于Web的应用程序。在这个基于 Web 的应用程序中,我有一个文本框,我将使用它来输入用户名。那么,我将如何才能将此用户名发送到该系统并将其用户信息检索到此应用程序?你能给我举个例子吗?
现在明白你真正需要什么了。实现此目的的最佳方法是使用 asp.net Web 服务。这意味着您必须对服务器上当前运行的代码进行一些编辑。
请查找 Asp.net Web 服务并查看以下链接:Microsoft Web 服务 Web 链接和创建和 ASP.NET 使用 Web 服务
如果你使用的是 .NET 3.5 及更高版本,则应查看 System.DirectoryServices.AccountManagement
(S.DS.AM( 命名空间。在这里阅读所有关于它的信息:
- 在 .NET Framework 3.5 中管理目录安全主体
- MSDN 文档 on System.DirectoryServices.AccountManagement
基本上,您可以定义域上下文并在 AD 中轻松查找用户和/或组:
// set up domain context
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
// find a user
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, "SomeUserName");
if(user != null)
{
// do something here....
}
// find the group in question
GroupPrincipal group = GroupPrincipal.FindByIdentity(ctx, "YourGroupNameHere");
// if found....
if (group != null)
{
// iterate over members
foreach (Principal p in group.GetMembers())
{
Console.WriteLine("{0}: {1}", p.StructuralObjectClass, p.DisplayName);
// do whatever you need to do to those members
}
}
新的 S.DS.AM 使在AD中玩弄用户和组变得非常容易!
正如"Nation"在他的回应中提到的,如果你把它"隐藏"在Web服务接口后面,那么各种应用程序都可以调用你的代码,并从Active Directory中获取他们需要的信息!