Introduction
Accessing the userProxy, userProxyFull objects from AD LDS through C# managed classes --
System.DirectoryServices.Accountmanagement
. The LDAP API in C# have only few classes to access Users and Groups. This article explains how to extend the principal classes to access
userProxy
,
userProxyFull
, person etc.. classes
Background
Recently, I had to work on a project which involved the work on extending the user schema in AD LDS instance. This has to facilitate to store some application specific data against the user. So we have extended the userProxy
and userProxyFull
classes schema to add few extra custom attributes.
There is a straight forward way to access the user, group classes through the UserPrincipal
and GroupPrincipal
classes, but these classes won't useful for, if you want to access the userProxy
, userProxyFull
or Person
classes. As I have searched online, not much documentation or online help to access these objects through the managed classes, so here I am trying to explain to extend the UserPrincipal
class to access the said objects.
Here I have extended the UserPrincipal
class to access such kind of classes from AD LDS or AD DS.
Here is the code
Here, we have created a class for accessing userProxy
, you can create similar extension classes for accessing other objects such as userProxyFull
and person etc...
using System;
using System.DirectoryServices.AccountManagement;
[DirectoryRdnPrefix("CN")]
[DirectoryObjectClass("userProxy")]
public class UserProxyPrincipal : UserPrincipal
{
public UserProxyPrincipal(PrincipalContext context)
: base(context)
{
}
public UserProxyPrincipal(PrincipalContext context,
string samAccountName,
string password,
bool enabled)
: base(context,
samAccountName,
password,
enabled)
{
}
UserProxyPrincipalSearchFilter searchFilter;
new public UserProxyPrincipalSearchFilter AdvancedSearchFilter
{
get
{
if (null == searchFilter)
searchFilter = new UserProxySearchFilter(this);
return searchFilter;
}
}
[DirectoryProperty("User-PostingID")]
public string PostingId
{
get
{
if (ExtensionGet("User-PostingID").Length != 1)
return null;
return (string)ExtensionGet("User-PostingID")[0];
}
set
{
ExtensionSet("User-PostingID", value);
}
}
[DirectoryProperty("distinguishedName")]
public string DistinguishedName
{
get
{
if (ExtensionGet("distinguishedName").Length != 1)
return null;
return (string)ExtensionGet("distinguishedName")[0];
}
set
{
ExtensionSet("distinguishedName", value);
}
}
[DirectoryProperty("otherHomePhone")]
public string[] HomePhoneOther
{
get
{
int len = ExtensionGet("otherHomePhone").Length;
string[] otherHomePhone = new string[len];
object[] otherHomePhoneRaw = ExtensionGet("otherHomePhone");
for (int i = 0; i < len; i++)
{
otherHomePhone[i] = (string)otherHomePhoneRaw[i];
}
return otherHomePhone;
}
set
{
ExtensionSet("otherHomePhone", value);
}
}
[DirectoryProperty("LogonCount")]
public Nullable<int> LogonCount
{
get
{
if (ExtensionGet("LogonCount").Length != 1)
return null;
return ((Nullable<int>)ExtensionGet("LogonCount")[0]);
}
}
public static new UserProxyPrincipal FindByIdentity(PrincipalContext context,
string identityValue)
{
return (UserProxyPrincipal)FindByIdentityWithType(context,
typeof(UserProxyPrincipal),
identityValue);
}
public static new UserProxyPrincipal FindByIdentity(PrincipalContext context,
IdentityType identityType,
string identityValue)
{
return (UserProxyPrincipal)FindByIdentityWithType(context,
typeof(UserProxyPrincipal),
identityType,
identityValue);
}
}
public class UserProxyPrincipalSearchFilter : AdvancedFilters
{
public UserProxyPrincipalSearchFilter(Principal p) : base(p) { }
public void LogonCount(int value, MatchType mt)
{
this.AdvancedFilterSet("LogonCount", value, typeof(int), mt);
}
}
The UserPrincipal
class is extended to hold the userProxy
objects, as you can see in the code the class is decorated with the tag
[DrectoryObjectClass("userProxy")
] , which makes to use the userProxy
objects from LDS. We can create the similar classes for userProxyFull
and person etc to access the data objects.
Using the code
public List GetAllUserProxies()
{
try
{
PrincipalContext oPrincipal = GetPrincipalContext();
UserProxyPrincipal inetPerson = UserProxyPrincipal.FindByIdentity(oPrincipal,
IdentityType.Name,
"pkola");
UserProxyPrincipal up = new UserProxyPrincipal(oPrincipal);
PrincipalSearcher srch = new PrincipalSearcher(up);
List list = new List();
foreach (var item in srch.FindAll())
{
list.Add(item as UserProxyPrincipal);
}
return list;
}
catch (Exception ex)
{
throw ex;
}
}
Hope this helped to you while extending the LDS user schemas with the application specific data.