DirectoryEntry - enum users/groups...

DirectoryEntry - enum users/groups...

Post by michael.ekegren[no-spam » Fri, 04 Jul 2003 21:27:58



Hi All

I'm strugling trying to create a WebControl which lists users and groups
from Active Directory.

The code using the DirectoryEntry and DirectorySearcher classes are
executed from a Windows 2003 server. The domain/active directory
controllor is on Windows 2000.

I have created a simple .Net Win-app which successfully lists users and
groups - the same code applied to a WebControl do not work. Either I
receive a SecurityException error - or something related to bad
username/password on the DirectoryEntry call.

I guess is has something to do with configuration of the assemblies or
other security settings. Can anyone help me on this issue?

Best regards
Michael Ekegren

 
 
 

DirectoryEntry - enum users/groups...

Post by MVP - ADS » Fri, 04 Jul 2003 23:13:07


Can you post the code that shows how you are binding your DirectoryEntry
objects?  This is most likely a problem with credentials or binding strings.
This article is very helpful:

http://support.microsoft.com/default.aspx?scid=kb;en-us;329986

Joe K.



Quote:> Hi All

> I'm strugling trying to create a WebControl which lists users and groups
> from Active Directory.

> The code using the DirectoryEntry and DirectorySearcher classes are
> executed from a Windows 2003 server. The domain/active directory
> controllor is on Windows 2000.

> I have created a simple .Net Win-app which successfully lists users and
> groups - the same code applied to a WebControl do not work. Either I
> receive a SecurityException error - or something related to bad
> username/password on the DirectoryEntry call.

> I guess is has something to do with configuration of the assemblies or
> other security settings. Can anyone help me on this issue?

> Best regards
> Michael Ekegren


 
 
 

DirectoryEntry - enum users/groups...

Post by michael.ekegren[no-spam » Sat, 05 Jul 2003 01:03:57


Hi Joe

Code snippet:
---

   DataSet ds = new DataSet();
   ds.Tables.Add();
   ds.Tables[0].Columns.Add(UserID);
   ds.Tables[0].Columns.Add(UserNTName);

   DirectoryEntry de = new DirectoryEntry(ldapPath); //THIS LINE FAILS
   DirectorySearcher mySearcher = new DirectorySearcher(de);
   mySearcher.PropertiesToLoad.Add("SAMAccountName");

   mySearcher.Filter = "(ObjectClass=User)";
   SearchResultCollection result = mySearcher.FindAll();
   foreach(SearchResult sr in result)
   {
    //DirectoryEntry user = sr.GetDirectoryEntry();
    DataRow dr = ds.Tables[0].NewRow();
    dr[UserID] = sr.Properties["SAMAccountName"][0];
    ds.Tables[0].Rows.Add(dr);
   }

----

ldapPath = LDAP://<AD SERVERNAME>/CN=Users,DC=domain,DC=com

<AD SERVERNAME> = Windows 2000 AD server (domain controllor), NOT same as
executing code

Hope this helps and can help you point me in the right direction.

Best regards
Michael Ekegren


> Can you post the code that shows how you are binding your DirectoryEntry
> objects?  This is most likely a problem with credentials or binding strings.
> This article is very helpful:

> http://support.microsoft.com/default.aspx?scid=kb;en-us;329986

> Joe K.



> > Hi All

> > I'm strugling trying to create a WebControl which lists users and groups
> > from Active Directory.

> > The code using the DirectoryEntry and DirectorySearcher classes are
> > executed from a Windows 2003 server. The domain/active directory
> > controllor is on Windows 2000.

> > I have created a simple .Net Win-app which successfully lists users and
> > groups - the same code applied to a WebControl do not work. Either I
> > receive a SecurityException error - or something related to bad
> > username/password on the DirectoryEntry call.

> > I guess is has something to do with configuration of the assemblies or
> > other security settings. Can anyone help me on this issue?

> > Best regards
> > Michael Ekegren

 
 
 

DirectoryEntry - enum users/groups...

Post by MVP - ADS » Sat, 05 Jul 2003 04:14:40


My guess is that the issue is with the credentials being used to bind to the
directory.  The link I provided in my previous post explains the issues with
ASP.NET and S.DS in a lot more detail than I can.  However, the crux of the
issue is probably the fact that the account the current thread is running
under cannot bind to the directory without supplying credentials (username
and password).  You may also need to supply a server name in your LDAP
binding string.

If the technote doesn't fix you up, then post back with more details about
how you have IIS configured, what you are doing with impersonation (if
anything), what the current windows account on your thread is
(System.Security.Principal.WindowsIdentity.GetCurrent().Name), etc. and we
should be able to get you going.

Joe K.



> Hi Joe

> Code snippet:
> ---

>    DataSet ds = new DataSet();
>    ds.Tables.Add();
>    ds.Tables[0].Columns.Add(UserID);
>    ds.Tables[0].Columns.Add(UserNTName);

>    DirectoryEntry de = new DirectoryEntry(ldapPath); //THIS LINE FAILS
>    DirectorySearcher mySearcher = new DirectorySearcher(de);
>    mySearcher.PropertiesToLoad.Add("SAMAccountName");

>    mySearcher.Filter = "(ObjectClass=User)";
>    SearchResultCollection result = mySearcher.FindAll();
>    foreach(SearchResult sr in result)
>    {
>     //DirectoryEntry user = sr.GetDirectoryEntry();
>     DataRow dr = ds.Tables[0].NewRow();
>     dr[UserID] = sr.Properties["SAMAccountName"][0];
>     ds.Tables[0].Rows.Add(dr);
>    }

> ----

> ldapPath = LDAP://<AD SERVERNAME>/CN=Users,DC=domain,DC=com

> <AD SERVERNAME> = Windows 2000 AD server (domain controllor), NOT same as
> executing code

> Hope this helps and can help you point me in the right direction.

> Best regards
> Michael Ekegren


> > Can you post the code that shows how you are binding your DirectoryEntry
> > objects?  This is most likely a problem with credentials or binding
strings.
> > This article is very helpful:

> > http://support.microsoft.com/default.aspx?scid=kb;en-us;329986

> > Joe K.



> > > Hi All

> > > I'm strugling trying to create a WebControl which lists users and
groups
> > > from Active Directory.

> > > The code using the DirectoryEntry and DirectorySearcher classes are
> > > executed from a Windows 2003 server. The domain/active directory
> > > controllor is on Windows 2000.

> > > I have created a simple .Net Win-app which successfully lists users
and
> > > groups - the same code applied to a WebControl do not work. Either I
> > > receive a SecurityException error - or something related to bad
> > > username/password on the DirectoryEntry call.

> > > I guess is has something to do with configuration of the assemblies or
> > > other security settings. Can anyone help me on this issue?

> > > Best regards
> > > Michael Ekegren

 
 
 

DirectoryEntry - enum users/groups...

Post by michael.ekegren[no-spam » Sat, 05 Jul 2003 04:25:05


Hi Joe

Thanks for your response. I have tried some of the methods on your posted link,
but if I do some of those changes the context of the WebControl is destroyed
(the WebControl is in fact a WebPart for Sharepoint Portal Server v2). The
application pool running have the identity of a domain administrator.

In the LDAP binding string - I actually provide a servername, if you look at my
previous post.

If I provide a domain account on the DirectoryEntry-call, using a named user,
password and Secure-authentication mode the call succeeds, but I don't want to
hardcode user/pass in my code, I would rather use the user credentials of the
logged in user (the user is authenticated - no anonymous access is allowed). I
just don't know how to do that.

System.Security.Principal.WindowsIdentity.GetCurrent().Name = my authenticated
user accessing the web page.

Hope you can provide my with additional tips - thanks for your help so far.

Best regards
Michael Ekegren


> My guess is that the issue is with the credentials being used to bind to the
> directory.  The link I provided in my previous post explains the issues with
> ASP.NET and S.DS in a lot more detail than I can.  However, the crux of the
> issue is probably the fact that the account the current thread is running
> under cannot bind to the directory without supplying credentials (username
> and password).  You may also need to supply a server name in your LDAP
> binding string.

> If the technote doesn't fix you up, then post back with more details about
> how you have IIS configured, what you are doing with impersonation (if
> anything), what the current windows account on your thread is
> (System.Security.Principal.WindowsIdentity.GetCurrent().Name), etc. and we
> should be able to get you going.

> Joe K.



> > Hi Joe

> > Code snippet:
> > ---

> >    DataSet ds = new DataSet();
> >    ds.Tables.Add();
> >    ds.Tables[0].Columns.Add(UserID);
> >    ds.Tables[0].Columns.Add(UserNTName);

> >    DirectoryEntry de = new DirectoryEntry(ldapPath); //THIS LINE FAILS
> >    DirectorySearcher mySearcher = new DirectorySearcher(de);
> >    mySearcher.PropertiesToLoad.Add("SAMAccountName");

> >    mySearcher.Filter = "(ObjectClass=User)";
> >    SearchResultCollection result = mySearcher.FindAll();
> >    foreach(SearchResult sr in result)
> >    {
> >     //DirectoryEntry user = sr.GetDirectoryEntry();
> >     DataRow dr = ds.Tables[0].NewRow();
> >     dr[UserID] = sr.Properties["SAMAccountName"][0];
> >     ds.Tables[0].Rows.Add(dr);
> >    }

> > ----

> > ldapPath = LDAP://<AD SERVERNAME>/CN=Users,DC=domain,DC=com

> > <AD SERVERNAME> = Windows 2000 AD server (domain controllor), NOT same as
> > executing code

> > Hope this helps and can help you point me in the right direction.

> > Best regards
> > Michael Ekegren


> > > Can you post the code that shows how you are binding your DirectoryEntry
> > > objects?  This is most likely a problem with credentials or binding
> strings.
> > > This article is very helpful:

> > > http://support.microsoft.com/default.aspx?scid=kb;en-us;329986

> > > Joe K.



> > > > Hi All

> > > > I'm strugling trying to create a WebControl which lists users and
> groups
> > > > from Active Directory.

> > > > The code using the DirectoryEntry and DirectorySearcher classes are
> > > > executed from a Windows 2003 server. The domain/active directory
> > > > controllor is on Windows 2000.

> > > > I have created a simple .Net Win-app which successfully lists users
> and
> > > > groups - the same code applied to a WebControl do not work. Either I
> > > > receive a SecurityException error - or something related to bad
> > > > username/password on the DirectoryEntry call.

> > > > I guess is has something to do with configuration of the assemblies or
> > > > other security settings. Can anyone help me on this issue?

> > > > Best regards
> > > > Michael Ekegren

 
 
 

DirectoryEntry - enum users/groups...

Post by MVP - ADS » Sun, 06 Jul 2003 02:59:36


My understanding is that to use impersonation successfully in S.DS with
Windows Integrated authentication in IIS, you also have to have all of your
users enabled for delegation, the server's machine account enabled to
delegate other accounts and Kerberos used throughout your application so
that delegation can work.  If those things are not possible, then you cannot
get impersonation to work reliably.

To be honest, I have never been able to get this to work in the environment
that I work in because our infrastructure folks have not been willing to
enable delegation on our user accounts, so often when people ask me these
questions, I can only speak from what I've read, not from personal
experience.

Another option you might be able to do would be to impersonate a specific
user account via web.config by specifying a username and password in the
identity element.  That still has you hardcoding an account, but it may be
your only solution.

I hope that helps some.  Good luck.

Joe K.



> Hi Joe

> Thanks for your response. I have tried some of the methods on your posted
link,
> but if I do some of those changes the context of the WebControl is
destroyed
> (the WebControl is in fact a WebPart for Sharepoint Portal Server v2). The
> application pool running have the identity of a domain administrator.

> In the LDAP binding string - I actually provide a servername, if you look
at my
> previous post.

> If I provide a domain account on the DirectoryEntry-call, using a named
user,
> password and Secure-authentication mode the call succeeds, but I don't
want to
> hardcode user/pass in my code, I would rather use the user credentials of
the
> logged in user (the user is authenticated - no anonymous access is
allowed). I
> just don't know how to do that.

> System.Security.Principal.WindowsIdentity.GetCurrent().Name = my
authenticated
> user accessing the web page.

> Hope you can provide my with additional tips - thanks for your help so
far.

> Best regards
> Michael Ekegren


> > My guess is that the issue is with the credentials being used to bind to
the
> > directory.  The link I provided in my previous post explains the issues
with
> > ASP.NET and S.DS in a lot more detail than I can.  However, the crux of
the
> > issue is probably the fact that the account the current thread is
running
> > under cannot bind to the directory without supplying credentials
(username
> > and password).  You may also need to supply a server name in your LDAP
> > binding string.

> > If the technote doesn't fix you up, then post back with more details
about
> > how you have IIS configured, what you are doing with impersonation (if
> > anything), what the current windows account on your thread is
> > (System.Security.Principal.WindowsIdentity.GetCurrent().Name), etc. and
we
> > should be able to get you going.

> > Joe K.



> > > Hi Joe

> > > Code snippet:
> > > ---

> > >    DataSet ds = new DataSet();
> > >    ds.Tables.Add();
> > >    ds.Tables[0].Columns.Add(UserID);
> > >    ds.Tables[0].Columns.Add(UserNTName);

> > >    DirectoryEntry de = new DirectoryEntry(ldapPath); //THIS LINE FAILS
> > >    DirectorySearcher mySearcher = new DirectorySearcher(de);
> > >    mySearcher.PropertiesToLoad.Add("SAMAccountName");

> > >    mySearcher.Filter = "(ObjectClass=User)";
> > >    SearchResultCollection result = mySearcher.FindAll();
> > >    foreach(SearchResult sr in result)
> > >    {
> > >     //DirectoryEntry user = sr.GetDirectoryEntry();
> > >     DataRow dr = ds.Tables[0].NewRow();
> > >     dr[UserID] = sr.Properties["SAMAccountName"][0];
> > >     ds.Tables[0].Rows.Add(dr);
> > >    }

> > > ----

> > > ldapPath = LDAP://<AD SERVERNAME>/CN=Users,DC=domain,DC=com

> > > <AD SERVERNAME> = Windows 2000 AD server (domain controllor), NOT same
as
> > > executing code

> > > Hope this helps and can help you point me in the right direction.

> > > Best regards
> > > Michael Ekegren


> > > > Can you post the code that shows how you are binding your
DirectoryEntry
> > > > objects?  This is most likely a problem with credentials or binding
> > strings.
> > > > This article is very helpful:

> > > > http://support.microsoft.com/default.aspx?scid=kb;en-us;329986

> > > > Joe K.


in

> > > > > Hi All

> > > > > I'm strugling trying to create a WebControl which lists users and
> > groups
> > > > > from Active Directory.

> > > > > The code using the DirectoryEntry and DirectorySearcher classes
are
> > > > > executed from a Windows 2003 server. The domain/active directory
> > > > > controllor is on Windows 2000.

> > > > > I have created a simple .Net Win-app which successfully lists
users
> > and
> > > > > groups - the same code applied to a WebControl do not work. Either
I
> > > > > receive a SecurityException error - or something related to bad
> > > > > username/password on the DirectoryEntry call.

> > > > > I guess is has something to do with configuration of the
assemblies or
> > > > > other security settings. Can anyone help me on this issue?

> > > > > Best regards
> > > > > Michael Ekegren

 
 
 

DirectoryEntry - enum users/groups...

Post by Willy Denoyette [MVP » Mon, 07 Jul 2003 06:41:16



Quote:> Another option you might be able to do would be to impersonate a specific
> user account via web.config by specifying a username and password in the
> identity element.  That still has you hardcoding an account, but it may be
> your only solution.

A better solution would be to access the DS from a server type COM+ application running with fixed identity.

Willy.

 
 
 

DirectoryEntry - enum users/groups...

Post by MVP - ADS » Mon, 07 Jul 2003 14:01:47


This seems like it would be effective as well, but it also seems like it
would add a lot of complexity for someone trying to deploy a web server
control.  What would be the real advantage of going with a separate COM+
component in this instance?  I'm pretty naive about COM+, so I'd like to
hear your opinion.

Joe K.






Quote:

> > Another option you might be able to do would be to impersonate a
specific
> > user account via web.config by specifying a username and password in the
> > identity element.  That still has you hardcoding an account, but it may
be
> > your only solution.

> A better solution would be to access the DS from a server type COM+

application running with fixed identity.
Quote:

> Willy.

 
 
 

DirectoryEntry - enum users/groups...

Post by michael.ekegren[no-spam » Tue, 08 Jul 2003 15:42:49


I have written other ADSI based COM+ components in vb6. But due to performance
and stability of these components I have the feeling that it would be a better
approach to wrap the ADSI like calls in .Net code using c#.

Speaking identity for the entire application pool in .Net - if I switch to
another user for the identity of such, then other applications might break.
Therefore I'm not interested in that solution. In ASP when running
NT-authenticated users towards the webserver, that identity was also executing
code (if you needed to impersonate, COM+ was the only option) - but this is not
the case in .Net?

Best regards
Michael


> This seems like it would be effective as well, but it also seems like it
> would add a lot of complexity for someone trying to deploy a web server
> control.  What would be the real advantage of going with a separate COM+
> component in this instance?  I'm pretty naive about COM+, so I'd like to
> hear your opinion.

> Joe K.





> > > Another option you might be able to do would be to impersonate a
> specific
> > > user account via web.config by specifying a username and password in the
> > > identity element.  That still has you hardcoding an account, but it may
> be
> > > your only solution.

> > A better solution would be to access the DS from a server type COM+
> application running with fixed identity.

> > Willy.

 
 
 

DirectoryEntry - enum users/groups...

Post by MVP - ADS » Tue, 08 Jul 2003 23:41:47


In ASP.NET under Windows Integrated authentication, the logged on user's
token is the token for the current request (impersonating) only when you
have impersonation turned on in web.config (it is off by default).  You need
to add the <identity impersonate="true"/> tag.

However, just because you are impersonating does not necessarily mean that
you can make requests on the network using that identity.  Unless the token
you have is a primary logon token (which won't be true with Windows
Integrated auth. as the password is not passed), then impersonation with a
network call such as ADSI/S.DS will not work unless you have enabled
delegation and the clients are binding via Kerberos like I said before.

Because of the complexity of getting this to work reliably, we generally
bypass the whole issue by using username and password for all of our S.DS
binds.  This requires us to store a secret password somewhere and is
potentially less secure, but ends up being more robust.  When we need to act
as the current user, we capture their credentials via the web application UI
and bind with those.

Joe K.



> I have written other ADSI based COM+ components in vb6. But due to
performance
> and stability of these components I have the feeling that it would be a
better
> approach to wrap the ADSI like calls in .Net code using c#.

> Speaking identity for the entire application pool in .Net - if I switch to
> another user for the identity of such, then other applications might
break.
> Therefore I'm not interested in that solution. In ASP when running
> NT-authenticated users towards the webserver, that identity was also
executing
> code (if you needed to impersonate, COM+ was the only option) - but this
is not
> the case in .Net?

> Best regards
> Michael


> > This seems like it would be effective as well, but it also seems like it
> > would add a lot of complexity for someone trying to deploy a web server
> > control.  What would be the real advantage of going with a separate COM+
> > component in this instance?  I'm pretty naive about COM+, so I'd like to
> > hear your opinion.

> > Joe K.




wrote

> > > > Another option you might be able to do would be to impersonate a
> > specific
> > > > user account via web.config by specifying a username and password in
the
> > > > identity element.  That still has you hardcoding an account, but it
may
> > be
> > > > your only solution.

> > > A better solution would be to access the DS from a server type COM+
> > application running with fixed identity.

> > > Willy.