ADSI code that will not work in asp.net

  • Thread starter msnews.microsoft.com
  • Start date
M

msnews.microsoft.com

I have ADSI code that I can make work at the command line. I cannot in
any way get it to work in asp.net. Even using Windows authentication,
impersonation on, and providing the credentials hardcoded, I cannot make
this same code happen. This is all I am trying to do:

static void Stuff()
{
//we don't need the credentials on this form
// so store in session state.

//look up computers from selected branch.
DataTable dt = new DataTable("Computers");
dt.Columns.Add("ComputerName");
DirectoryEntry de = new
DirectoryEntry("LDAP://CN=Computers,DC=TOPDOMAIN,DC=CA");
de.Username = "adminishtypeaccount";
de.Password = "biglongpasswordofsomesort";
DirectorySearcher ds = new DirectorySearcher(de);

//try
{
foreach(SearchResult sr in ds.FindAll())
{
DataRow dr = dt.NewRow();
dr["ComputerName"] = sr.GetDirectoryEntry().Name.ToString();
dt.Rows.Add(dr);
}
}
//catch
{
//no action for now.
}

/* web version attaches
to a grid then binds
- only difference */
DataSet MySet = new DataSet();
MySet.Tables.Add(dt);
Console.WriteLine(MySet.GetXml());
Console.ReadLine();
}
}
 
M

msnews.microsoft.com

Ken said:
Is it possible that you are providing credentials to access to ADSI but not
to access the remote server itself? At the command line, yours would be
passed through. ASP.NET wouldn't do that the same way.

Not sure, but I'd look into NetworkCredential Class to get ASP.NET into the
machine itself:

http://msdn.microsoft.com/library/d...frlrfsystemnetnetworkcredentialclasstopic.asp

Let us know when you get it working?

Ken

Thanks for the suggestion. How would you do this if you're not sure
which AD server is going to be doing the authenticating? There is more
than one on our network, and I'd hate to have to target it specifically
for connection.

Richard
 
J

Joe Kaplan \(MVP - ADSI\)

This is pretty well documented here:

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

Generally, the problem is that when you don't supply a server or domain name
in our binding string or don't supply credentials in your directoryentry
constructor, the ADSI components will try to infer them from the current
security context. In ASP.NET, you are often running as a local machine
account, so this won't work when trying to get domain information or
credentials. When you run the code locally, it picks up your domain
credentials and domain controller information from that.

To verify this is the problem, add a domain controller to your binding
string (LDAP://mydc.com/CN=xxxx) and provide valid credentials for the
username and password properties. If that works, then that is the problem.

If you don't want to specific a DC or credentials, there are a bunch of ways
around this as ASP.NET gives you lots of security options. They all have
good points and bad points.

Joe K.
 
J

Joe Kaplan \(MVP - ADSI\)

You've got a couple of options if you want to this to be dynamic:

- You can change the security context so that a domain user is used. This
will get you a valid domain controller that can be used in a "serverless"
bind and should get you valid credentials that can be used. To do this, you
can either:
Change the process identity for ASP.NET to a domain account, either with the
processModel setting in web.config for IIS5 or the app pool identity for
IIS6, or impersonate a windows user or lace the code in a COM+ dll and set
that up to use a domain identity. Impersonation works well if you are using
Windows auth in your application, but you may have delegation issues with
that. Please read the doc in the link I posted in my other reply.

- You can also specify a domain or domain controller name and put it in
web.config so you can change it at runtime. If you specify a domain name
instead of an actual DC, the underlying system will use DNS to determine a
DC to use at runtime. However, this doesn't solve the credentials problem,
so you may still need to provide those (via config again).

All of the various approaches have good points and bad points. I generally
go with setting values via configuration, but I will use the "security
context" approaches sometimes as well. The important thing to know is WHY
the code works and what it depends on so that when you change something
later, you'll know why it broke.

HTH,

Joe K.
 
R

Richard Bethell

OK - I'm still struggling with ADSI and asp.net, as another angle of
this project has forced me back at it. ADSI and asp.net are two things
definitely not made to work together, from what I can tell.

At any rate, I'm at the desperate point where I will try anything, but
don't know how to use the NetworkCredential class against this AD server
- it is not a SOAP server, and offers up no http services of any kind.

Does this class come into play for just the simple attempt to try and
gain some access to the AD services?

I just want to do some very simple things... I can't believe what a
difficult struggle this is.

R.
 
S

Steven Cheng[MSFT]

Hi Richard,

I think this should be a normal issue that the DirectoryService processing
work well under winform/console app but fail in asp.net. What's the error
info you got when failing in accessing the AD?
Here is a kb artcle discussing on this detailedly.

#How to use the System.DirectoryServices namespace in ASP.NET
http://support.microsoft.com/?id=329986

It has mentioned serveral important points such as require a Primary Token
and possible double hop issue....
Also, you can try some of the troubleshooting approachs in it.

Hope helps. Thanks.


Regards,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
R

Richard Bethell

but not to access the remote server itself? At the command line,
yours would be passed through. ASP.NET wouldn't do that the same way.

Not sure, but I'd look into NetworkCredential Class to get ASP.NET
into the machine itself:

http://msdn.microsoft.com/library/d...frlrfsystemnetnetworkcredentialclasstopic.asp


Let us know when you get it working?

Well, I couldn't find any way to use this class, but I did find a way to
get credentials passing in a way that had more force. I put the code
inside an impersonation block, opening with this:

System.Security.Principal.WindowsImpersonationContext impersonationContext;
impersonationContext =

((System.Security.Principal.WindowsIdentity)HttpContext.Current.User.Identity).Impersonate();


Funny - the impersonation flag in web.config was not as effective as this.

Richard
 
S

Steven Cheng[MSFT]

Hi Richard,

Thanks for your followup. Yes, as for the impersonation via web.config or
programly impersonation. There maybe some difference on the crediential
they generated.

1. When using the web.config impersonation, if we don't specify the
username and PASSWORD as clear text in the <identity> element, asp.net will
use the account passed from IIS. And the identity token passed by IIS
depend on the authentication mode it use, if use Integrited Windows, the
passed token is not a primary token(you can refer to the kb I provided in
the last message) and which can't be double hop to remote machine. If using
basic authentication, since the client user must provide clear text
password, so the passed
token can be used to double hop to remote machine.

2. When using code to programly impersonate, we will provide the cleartext
password, so the generated identity token is also double-hopable. And the
effect is as same as we speicfying a fixed account (with clear USERNAME
PASSWORD) in web.config's <idenity > element or use BASIC authenticaiton
in IIS and impersonate the client user identity from IIS.

Anyway, glad that you've resolved the problem. And you may have a look at
the kb article in my last reply. If there are any further questions, please
feel free to post here. Thanks.


Regards,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top