Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / ASP.NET / Security / October 2007

Tip: Looking for answers? Try searching our database.

The pest of Impersonation

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Cliff - 24 Sep 2007 17:43 GMT
I have an ASP Website setup which presents some data, then posts
changes to that data to another webpage (whcih is java based) by using
variables on the URL Line, the Java website trapps the user's details
and places some information against the closed call, such as who
closed it.

This works ok....and here's the code

string number = ((CloseParams)o).number;
       string CloseText = ((CloseParams)o).closecomment;
       WebClient wc = new WebClient();
       wc.UseDefaultCredentials = true;

       Uri uri = new Uri("http://callsite/getservices/
view_specific_update_action.cfm?number="
           + number + "&Resolution=" +
HttpUtility.UrlEncode(CloseText) + "&subclose=" +
HttpUtility.UrlEncode("Close Ticket"));
       string result = wc.DownloadString(uri);

The website on the other side of this (callsite) is supposed to be
trapping the currently logged on user (through integrated
authentication) and placing the logged on user details on the call.

if you access the callsite through ie everything works fine.

However...by accessing my site wihch is in ASP.NET that information
does not get passed through.

If in my code I do

Debug.WriteLine(this.User.Identity.Name.ToString());

I get the username of the currently logged on user to my asp.net
site....which is what I would expect. That user should be what is
passing across to the other site....surely???

The guys who own the Java site are saying they are seeing the server
that my site is running on as the account that is closing tickets..

I've made a few changes to things

I've tried setting Impersonate = true and false in web.config.

I've tried changing the identity in the App Pool to Local Service and
Local System

I've tried changing the code to run the old fashioned way:

       HttpWebRequest req =
(HttpWebRequest)WebRequest.Create(uri.ToString());
       string username =
System.Security.Principal.WindowsIdentity.GetCurrent().Name;
       EventLog.WriteEntry("AutoGen close tool", "User " + username +
"\n" + "Executed the URL: " +
uri.ToString());
       WebResponse response = req.GetResponse();
       StreamReader sr = new
StreamReader(response.GetResponseStream());
       string tmp = sr.ReadToEnd();

i.e. using Webrequest instead of WebClient

I've also tried doing an explicit impersonation

       HttpWebRequest req =
(HttpWebRequest)WebRequest.Create(uri.ToString());

       System.Security.Principal.WindowsImpersonationContext
impersonationContext;
       impersonationContext =

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

       string username =
System.Security.Principal.WindowsIdentity.GetCurrent().Name;
       EventLog.WriteEntry("AutoGen close tool", "User " + username +
"\n" + "Executed the URL: " + uri.ToString());

       WebResponse response = req.GetResponse();
       StreamReader sr = new
StreamReader(response.GetResponseStream());
       string tmp = sr.ReadToEnd();

but none of that works!

How can I put the call across to the Callsite website using the
credentials of the user thats accessing my website?

Cliff.
Joe Kaplan - 24 Sep 2007 18:56 GMT
This sounds like a double hop issue which typically would require Kerberos
delegation to fix.  What type of authentication is used on the ASP.NET site?
If it is integrated auth, then you will need to implement Kerberos
delegation to get the credentials to flow from the browser to your web site
to a web site that it calls.

Joe K.

Signature

Joe Kaplan-MS MVP Directory Services Programming
Co-author of "The .NET Developer's Guide to Directory Services Programming"
http://www.directoryprogramming.net
--

>I have an ASP Website setup which presents some data, then posts
> changes to that data to another webpage (whcih is java based) by using
[quoted text clipped - 86 lines]
>
> Cliff.
Cliff - 25 Sep 2007 18:16 GMT
On 24 Sep, 18:56, "Joe Kaplan"
<joseph.e.kap...@removethis.accenture.com> wrote:
> This sounds like a double hop issue which typically would require Kerberos
> delegation to fix.  What type of authentication is used on the ASP.NET site?
[quoted text clipped - 100 lines]
>
> - Show quoted text -

hi. Thanks for that, I've given the server the "trusted for
Delegation" right in AD and given it a re-boot, but still no avail...

for reference: The site is set as Integrated and Digest authentication

The Application Pool has been tried under Local Service, Network
Service and Local System

The web.config file is set to <Authentication Mode="Windows"/> and
<identity impersonate="true"/>

Many thanks!

Cliff.
Joe Kaplan - 26 Sep 2007 05:42 GMT
A few things here.  It sounds like either your AD is Win2K or is still and
2K functional level, as your description makes it sound like the only option
available for delegation is "trusted for delegation".  With a 2K3 native
forest, you can also do protocol transition and constrained delegation and
the delegation tab in ADUC has more options.

So, assuming you only have "trusted for delegation" available, that requires
Kerberos auth for the both the front end web app as well as your target
backend system.  If you were able to enable protocol transition ("trusted to
delegate with any protocol" in ADUC), then you could have the front end web
app authenticate using NTLM, Basic or Digest in addition to Kerberos.

You'll need to run the app pool as Network Service (preferred) or Local
System in order for the machine account's credentials to be used on the
network.  Since that's where you applied the delegation, it is important for
that account to be used.

So, given all that, the first thing you need to do is ensure that you are
getting Kerberos authentication in the front end web app, not NTLM.  Turn
off Digest.  You can't use it in this scenario, so it is best that your
server doesn't even advertise it as an option.  To determine whether you are
getting Kerberos auth, the best way is to enable auditing for both success
and failure of logon events in your local security policy and look at the
details of the authentication events that are logged when you sign in via
the browser.  If those say NTLMSSP instead of Kerberos, then you aren't
getting Kerberos auth in the web app and you have to fix that.  Reading the
TechNet docs on troubleshooting Kerberos auth is essential.

Once you get Kerb auth on the front end, then you need to also ensure you
get Kerb auth on the backend.  After that, you can delegate using
impersonation of the authenticated user in the web app.

Joe K.

Signature

Joe Kaplan-MS MVP Directory Services Programming
Co-author of "The .NET Developer's Guide to Directory Services Programming"
http://www.directoryprogramming.net
--

>
> hi. Thanks for that, I've given the server the "trusted for
[quoted text clipped - 11 lines]
>
> Cliff.
Cliff - 26 Sep 2007 10:43 GMT
On 26 Sep, 05:42, "Joe Kaplan"
<joseph.e.kap...@removethis.accenture.com> wrote:
> A few things here.  It sounds like either your AD is Win2K or is still and
> 2K functional level, as your description makes it sound like the only option
[quoted text clipped - 51 lines]
>
> - Show quoted text -

WOW...there's alot there and I'll certainly give that a go.

We are Windows 2003 Native tho, I didn't mention the other options as
I thought I'd start with the simplest option which is just "Trusted
for Delegation".

Thanks again for your help...I'll post back when I've completed those
steps.

Cliff.
Cliff - 27 Sep 2007 16:00 GMT
> On 26 Sep, 05:42, "Joe Kaplan"
>
[quoted text clipped - 67 lines]
>
> - Show quoted text -

ok, I've made the changes to AD, to allow the relavant services to do
any form of delegation

I've re-booted and still nothing.

I checked the security event log of my web site and authentication to
my website is Kerberos, and appears to be working fine.

I don't have any access to the other "Java" based website, so I'm un-
able to tell how that is doing authentication.

Surely there's some way in dotnet I could monitor that...to see what
the code is doing and how my authentication is being done on the
foreign machine.

Would it show up if I were to monitor the network traffic using
ehereal or something like that?

Cliff.
Joe Kaplan - 27 Sep 2007 22:29 GMT
Hi Cliff,

You need to find out whether it is possible to do Kerberos-based auth to the
Java web site that you are calling from the server that you are connecting
from.  If Kerb auth is possible there, then delegation is also possible
here.

If you don't have access to that server, you won't be able to see its event
logs.  However, you can look at the network traces taken from the front end
web server and examine the traffic to the backend.  If Kerberos auth is
being performed, then you'll see that.  If it is falling over to NTLM, then
you'll see that instead (although it may not be easy to tell what you are
looking at from a network level if you haven't had much experience looking
at these traces).

The tool I like to use for testing Kerberos auth for HTTP endpoints is a
little GUI tool that comes with the IIS 6 Resource Kit (free download)
called wfetch.  It allows you to issue an HTTP request of your choice (GET,
POST, etc.) to a resource and specify the auth you want to do and the
credentials you want to use.  To test Kerberos auth, you would select the
Negotiate authentication protocol option.  With some experience, you may be
able to tell what type of auth was performed simply by looking at the HTTP
traffic that wfetch shows.  However, combining that with a network sniff
will tell you.

Like I said, this stuff can be pretty hard to troubleshoot.

Joe K.

Signature

Joe Kaplan-MS MVP Directory Services Programming
Co-author of "The .NET Developer's Guide to Directory Services Programming"
http://www.directoryprogramming.net
--

>
> ok, I've made the changes to AD, to allow the relavant services to do
[quoted text clipped - 16 lines]
>
> Cliff.
Cliff - 03 Oct 2007 15:41 GMT
On 27 Sep, 22:29, "Joe Kaplan"
<joseph.e.kap...@removethis.accenture.com> wrote:
> Hi Cliff,
>
[quoted text clipped - 51 lines]
>
> - Show quoted text -

right, I have lots more information

I've done some thourough testing, and I've got myself access to the
foreign webserver.

If i access the java webserver via ie....I see "Kerberos" based
authentication events in the security log.

I've tried just about everything under the sun with my website, but
with "impersonation" off, I only ever authenticate as the servername,
with impersonation on (and it doesn't seem to matter what type of
impersonation i use) I get access denied, or more preciecely 401 which
is autorization failed.

I've looked at the Security log on the Java website and when the
asp.net server is not impersonating, I get a kerberos login for the
server name

When impersonation is switched on, I get an "Anonymous Logon" and some
talk of NTLM:

Successful Network Logon:
    User Name:
    Domain:
    Logon ID:        (0x0,0x9FF8B8A)
    Logon Type:    3
    Logon Process:    NtLmSsp
    Authentication Package:    NTLM
    Workstation Name:    asp.net web server
    Logon GUID:    -
    Caller User Name:    -
    Caller Domain:    -
    Caller Logon ID:    -
    Caller Process ID: -
    Transited Services: -
    Source Network Address:    removed
    Source Port:    1773

So, to summarise

The Java website does accept KERBEROS authentication
I am definatly logged on and authenticated to the ASP.NET website
The authentication isn't getting through when I switch to
impersonation.

Cliff.
Joe Kaplan - 03 Oct 2007 16:16 GMT
Ok, so in this case it is just the delegation that is failing.  This is
actually a good sign.

What you are seeing is that Kerberos auth using impersonation cannot be done
for whatever reason (which we need to figure out), so Negotiate auth tries
NTLM instead and logs in the anonymous (NULL token) user.  Since no one in
their right mind grants any access to the anonymous user, you get a 401.

Since it looks like the app pool identity (impersonation off) CAN do Kerb
auth the other web server and you don't have a configuration problem with an
SPN or IIS setting, it looks like you just don't have rights to delegate.

Are you certain that the app pool identity for the front end web server has
permissions to delegate in AD?  Also, are the browser clients being
authenticated with Kerberos on the front end?  If those two are true, then
delegation should be possible.

It has been a little while since I looked at this thread, so you might have
to remind me exactly which steps have been confirmed.

Joe K.

Signature

Joe Kaplan-MS MVP Directory Services Programming
Co-author of "The .NET Developer's Guide to Directory Services Programming"
http://www.directoryprogramming.net
--

> right, I have lots more information
>
[quoted text clipped - 42 lines]
>
> Cliff.
Cliff - 22 Oct 2007 14:18 GMT
On Oct 3, 4:16 pm, "Joe Kaplan"
<joseph.e.kap...@removethis.accenture.com> wrote:
> Ok, so in this case it is just the delegation that is failing.  This is
> actually a good sign.
[quoted text clipped - 71 lines]
>
> - Show quoted text -

I thought I'd follow this up with an epilogue of how I fixed this
problem in the end.

There were 2 basic problems;

1, The Delegate tab in AD says "Trust this computer for delegation to
the specified services only".

I'd read that as meaning....these services are trusted to delegate the
logged in user to another machine and present the credentials
accordingly.

but thats not what it says....it says TO! so once I'd added the
foreign machine in, things started to work...

but that wasn't the end of the story

2, asp.net isn't thread and impersonation friendly.

One peice of information I left out of the description above was that
these calls were being made in child threads of the asp.net process.
(for performance reasons)

and by default it appears dotnet doesn't allow impersonation to flow
to the new thread. so although I could prove in my "asp.net" thread I
could impersonate across, when I actually made the request in the
child thread, the impersonation was lost. (!?!?!?!?!?)

it turns out that behavour is by design (argh!) and you can revert to
the old behaviour....which is what I wanted in this case

hence we look at the aspnet.config file and we find the following:

<configuration>
 <runtime>
   <legacyUnhandledExceptionPolicy enabled="false" />
   <SymbolReadingPolicy enabled="1" />
   <legacyImpersonationPolicy enabled="true" />
   <alwaysFlowImpersonationPolicy enabled="false" />
 </runtime>
<configuration>

Inverting Legacy impersionationPolicy and
alwaysFlowImpersonationPolicy over solved the problem and
impersonation now flows correctly.

Cliff.

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.