Impersonation using WindowsIdentity( upn ) ctor

A

Alberto Ortega

I'm trying to impersonate a user using the WindowsIdentity ctor. This is
what I'm doing

WindowsIdentity id = new WindowsIdentity( "(e-mail address removed)-dev.net" );
WindowsImpersonationContext wic = id.Impersonate();
try
{
DoSome();
}
finally
{
wic.Undo();
}

I'm getting this exception

Access is denied.
Description: An unhandled exception occurred during the execution of the
current web request. Please review the stack trace for more information
about the error and where it originated in the code.

Exception Details: System.ApplicationException: Access is denied.

[ApplicationException: Access is denied.
]
System.Security.Principal.WindowsIdentity._ResolveIdentity(IntPtr
userToken) +0
System.Security.Principal.WindowsIdentity.get_Name() +70
ImpersonationTest.WebForm1.DoSome() in
c:\inetpub\wwwroot\impersonationtest\webform1.aspx.cs:71
ImpersonationTest.WebForm1.ImpersonateWinId() in
c:\inetpub\wwwroot\impersonationtest\webform1.aspx.cs:41
ImpersonationTest.WebForm1.Page_Load(Object sender, EventArgs e) in
c:\inetpub\wwwroot\impersonationtest\webform1.aspx.cs:29
System.Web.UI.Control.OnLoad(EventArgs e) +67
System.Web.UI.Control.LoadRecursive() +35
System.Web.UI.Page.ProcessRequestMain() +750



The configuration is:

* IIS: Anonynous checkbox ON and Integrated Security checkbox ON

* Web.config: <identity impersonate="true"> and <authentication
mode="Forms"> (auth mode forms is a requisite non negotiable on my app)

* The app pool for the virtual dir is configured with Network Service

Running on Win2K3 Domain Controller

Any idea of what I should do to make the impersonation work?

Thanks,
Beto
 
J

Joe Kaplan \(MVP - ADSI\)

The problem is fairly subtle and is related to how Kerberos S4U, or
"protocol transition", works. That is the new Windows 2003 feature that you
are using under the hood when you use the WindowsIdentity "UPN" ctor.

With S4U, the token returned by the API will either be an Impersonation
level token or an Identity level token. The level depends on whether or not
the account creating the token has the "Act as part of the operating system"
privilege. Only accounts with with that privilege can create an
Impersonation level token with S4U. By default, only the SYSTEM account has
this privilege. Everything else will create an Identify level token.

As you probably guessed, a token has to be Impersonation level in order to
impersonate it. An identify-level token can only be used to do things like
check group membership and such. This is the error that you are seeing.

This limitation is actually a security feature. When you think about it,
you wouldn't really want any old account having the ability to create a
token for a user at random with no credentials for that user and then start
executing code on their behalf!

If you have a situation where you absolutely need to do this, you need to
run the code with an account with the act as part of the operating system
privilege. If you do that, you probably want to think very very carefully
about how you are going to secure this as you are potentially opening a
massive security hole by doing this. Tread very lightly here.

Joe K.

Alberto Ortega said:
I'm trying to impersonate a user using the WindowsIdentity ctor. This is
what I'm doing

WindowsIdentity id = new WindowsIdentity( "(e-mail address removed)-dev.net" );
WindowsImpersonationContext wic = id.Impersonate();
try
{
DoSome();
}
finally
{
wic.Undo();
}

I'm getting this exception

Access is denied.
Description: An unhandled exception occurred during the execution of the
current web request. Please review the stack trace for more information
about the error and where it originated in the code.

Exception Details: System.ApplicationException: Access is denied.

[ApplicationException: Access is denied.
]
System.Security.Principal.WindowsIdentity._ResolveIdentity(IntPtr
userToken) +0
System.Security.Principal.WindowsIdentity.get_Name() +70
ImpersonationTest.WebForm1.DoSome() in
c:\inetpub\wwwroot\impersonationtest\webform1.aspx.cs:71
ImpersonationTest.WebForm1.ImpersonateWinId() in
c:\inetpub\wwwroot\impersonationtest\webform1.aspx.cs:41
ImpersonationTest.WebForm1.Page_Load(Object sender, EventArgs e) in
c:\inetpub\wwwroot\impersonationtest\webform1.aspx.cs:29
System.Web.UI.Control.OnLoad(EventArgs e) +67
System.Web.UI.Control.LoadRecursive() +35
System.Web.UI.Page.ProcessRequestMain() +750



The configuration is:

* IIS: Anonynous checkbox ON and Integrated Security checkbox ON

* Web.config: <identity impersonate="true"> and <authentication
mode="Forms"> (auth mode forms is a requisite non negotiable on my app)

* The app pool for the virtual dir is configured with Network Service

Running on Win2K3 Domain Controller

Any idea of what I should do to make the impersonation work?

Thanks,
Beto
 
A

Alberto Ortega

Ok, now, what if I use the LogonUser API ?

Thanks a lot.
Beto.

Joe Kaplan (MVP - ADSI) said:
The problem is fairly subtle and is related to how Kerberos S4U, or
"protocol transition", works. That is the new Windows 2003 feature that you
are using under the hood when you use the WindowsIdentity "UPN" ctor.

With S4U, the token returned by the API will either be an Impersonation
level token or an Identity level token. The level depends on whether or not
the account creating the token has the "Act as part of the operating system"
privilege. Only accounts with with that privilege can create an
Impersonation level token with S4U. By default, only the SYSTEM account has
this privilege. Everything else will create an Identify level token.

As you probably guessed, a token has to be Impersonation level in order to
impersonate it. An identify-level token can only be used to do things like
check group membership and such. This is the error that you are seeing.

This limitation is actually a security feature. When you think about it,
you wouldn't really want any old account having the ability to create a
token for a user at random with no credentials for that user and then start
executing code on their behalf!

If you have a situation where you absolutely need to do this, you need to
run the code with an account with the act as part of the operating system
privilege. If you do that, you probably want to think very very carefully
about how you are going to secure this as you are potentially opening a
massive security hole by doing this. Tread very lightly here.

Joe K.

Alberto Ortega said:
I'm trying to impersonate a user using the WindowsIdentity ctor. This is
what I'm doing

WindowsIdentity id = new WindowsIdentity( "(e-mail address removed)-dev.net" );
WindowsImpersonationContext wic = id.Impersonate();
try
{
DoSome();
}
finally
{
wic.Undo();
}

I'm getting this exception

Access is denied.
Description: An unhandled exception occurred during the execution of the
current web request. Please review the stack trace for more information
about the error and where it originated in the code.

Exception Details: System.ApplicationException: Access is denied.

[ApplicationException: Access is denied.
]
System.Security.Principal.WindowsIdentity._ResolveIdentity(IntPtr
userToken) +0
System.Security.Principal.WindowsIdentity.get_Name() +70
ImpersonationTest.WebForm1.DoSome() in
c:\inetpub\wwwroot\impersonationtest\webform1.aspx.cs:71
ImpersonationTest.WebForm1.ImpersonateWinId() in
c:\inetpub\wwwroot\impersonationtest\webform1.aspx.cs:41
ImpersonationTest.WebForm1.Page_Load(Object sender, EventArgs e) in
c:\inetpub\wwwroot\impersonationtest\webform1.aspx.cs:29
System.Web.UI.Control.OnLoad(EventArgs e) +67
System.Web.UI.Control.LoadRecursive() +35
System.Web.UI.Page.ProcessRequestMain() +750



The configuration is:

* IIS: Anonynous checkbox ON and Integrated Security checkbox ON

* Web.config: <identity impersonate="true"> and <authentication
mode="Forms"> (auth mode forms is a requisite non negotiable on my app)

* The app pool for the virtual dir is configured with Network Service

Running on Win2K3 Domain Controller

Any idea of what I should do to make the impersonation work?

Thanks,
Beto
 
J

Joe Kaplan \(MVP - ADSI\)

You can definitely impersonate a token created with LogonUser.

I'd use the sample code in the .NET SDK docs for
WindowsImpersonationContext. They have a one of the best ones I've seen.

Joe K.

Alberto Ortega said:
Ok, now, what if I use the LogonUser API ?

Thanks a lot.
Beto.

Joe Kaplan (MVP - ADSI) said:
The problem is fairly subtle and is related to how Kerberos S4U, or
"protocol transition", works. That is the new Windows 2003 feature that you
are using under the hood when you use the WindowsIdentity "UPN" ctor.

With S4U, the token returned by the API will either be an Impersonation
level token or an Identity level token. The level depends on whether or not
the account creating the token has the "Act as part of the operating system"
privilege. Only accounts with with that privilege can create an
Impersonation level token with S4U. By default, only the SYSTEM account has
this privilege. Everything else will create an Identify level token.

As you probably guessed, a token has to be Impersonation level in order
to
impersonate it. An identify-level token can only be used to do things like
check group membership and such. This is the error that you are seeing.

This limitation is actually a security feature. When you think about it,
you wouldn't really want any old account having the ability to create a
token for a user at random with no credentials for that user and then start
executing code on their behalf!

If you have a situation where you absolutely need to do this, you need to
run the code with an account with the act as part of the operating system
privilege. If you do that, you probably want to think very very
carefully
about how you are going to secure this as you are potentially opening a
massive security hole by doing this. Tread very lightly here.

Joe K.

Alberto Ortega said:
I'm trying to impersonate a user using the WindowsIdentity ctor. This
is
what I'm doing

WindowsIdentity id = new WindowsIdentity( "(e-mail address removed)-dev.net" );
WindowsImpersonationContext wic = id.Impersonate();
try
{
DoSome();
}
finally
{
wic.Undo();
}

I'm getting this exception

Access is denied.
Description: An unhandled exception occurred during the execution of
the
current web request. Please review the stack trace for more information
about the error and where it originated in the code.

Exception Details: System.ApplicationException: Access is denied.

[ApplicationException: Access is denied.
]
System.Security.Principal.WindowsIdentity._ResolveIdentity(IntPtr
userToken) +0
System.Security.Principal.WindowsIdentity.get_Name() +70
ImpersonationTest.WebForm1.DoSome() in
c:\inetpub\wwwroot\impersonationtest\webform1.aspx.cs:71
ImpersonationTest.WebForm1.ImpersonateWinId() in
c:\inetpub\wwwroot\impersonationtest\webform1.aspx.cs:41
ImpersonationTest.WebForm1.Page_Load(Object sender, EventArgs e) in
c:\inetpub\wwwroot\impersonationtest\webform1.aspx.cs:29
System.Web.UI.Control.OnLoad(EventArgs e) +67
System.Web.UI.Control.LoadRecursive() +35
System.Web.UI.Page.ProcessRequestMain() +750



The configuration is:

* IIS: Anonynous checkbox ON and Integrated Security checkbox ON

* Web.config: <identity impersonate="true"> and <authentication
mode="Forms"> (auth mode forms is a requisite non negotiable on my app)

* The app pool for the virtual dir is configured with Network Service

Running on Win2K3 Domain Controller

Any idea of what I should do to make the impersonation work?

Thanks,
Beto
 
D

Dominick Baier [DevelopMentor]

Hello Alberto,

you need the password when calling LogonUser - how will you safely store
that in your app??

dominick baier - DevelopMentor
www.leastprivilege.com

Ok, now, what if I use the LogonUser API ?

Thanks a lot.
Beto.
The problem is fairly subtle and is related to how Kerberos S4U, or
"protocol transition", works. That is the new Windows 2003 feature
that
you

are using under the hood when you use the WindowsIdentity "UPN" ctor.

With S4U, the token returned by the API will either be an
Impersonation level token or an Identity level token. The level
depends on whether or
not

the account creating the token has the "Act as part of the operating
system"

privilege. Only accounts with with that privilege can create an
Impersonation level token with S4U. By default, only the SYSTEM
account
has

this privilege. Everything else will create an Identify level token.

As you probably guessed, a token has to be Impersonation level in
order to impersonate it. An identify-level token can only be used to
do things
like

check group membership and such. This is the error that you are
seeing.

This limitation is actually a security feature. When you think about
it, you wouldn't really want any old account having the ability to
create a token for a user at random with no credentials for that user
and then
start

executing code on their behalf!

If you have a situation where you absolutely need to do this, you
need to run the code with an account with the act as part of the
operating system privilege. If you do that, you probably want to
think very very carefully about how you are going to secure this as
you are potentially opening a massive security hole by doing this.
Tread very lightly here.

Joe K.

I'm trying to impersonate a user using the WindowsIdentity ctor.
This is what I'm doing

WindowsIdentity id = new WindowsIdentity( "(e-mail address removed)-dev.net"
);
WindowsImpersonationContext wic = id.Impersonate();
try
{
DoSome();
}
finally
{
wic.Undo();
}
I'm getting this exception

Access is denied.
Description: An unhandled exception occurred during the execution of
the
current web request. Please review the stack trace for more
information
about the error and where it originated in the code.
Exception Details: System.ApplicationException: Access is denied.

[ApplicationException: Access is denied.
]
System.Security.Principal.WindowsIdentity._ResolveIdentity(IntPtr
userToken) +0
System.Security.Principal.WindowsIdentity.get_Name() +70
ImpersonationTest.WebForm1.DoSome() in
c:\inetpub\wwwroot\impersonationtest\webform1.aspx.cs:71
ImpersonationTest.WebForm1.ImpersonateWinId() in
c:\inetpub\wwwroot\impersonationtest\webform1.aspx.cs:41
ImpersonationTest.WebForm1.Page_Load(Object sender, EventArgs e) in
c:\inetpub\wwwroot\impersonationtest\webform1.aspx.cs:29
System.Web.UI.Control.OnLoad(EventArgs e) +67
System.Web.UI.Control.LoadRecursive() +35
System.Web.UI.Page.ProcessRequestMain() +750
The configuration is:

* IIS: Anonynous checkbox ON and Integrated Security checkbox ON

* Web.config: <identity impersonate="true"> and <authentication
mode="Forms"> (auth mode forms is a requisite non negotiable on my
app)

* The app pool for the virtual dir is configured with Network
Service

Running on Win2K3 Domain Controller

Any idea of what I should do to make the impersonation work?

Thanks,
Beto
 
M

Matias Woloski

Hi, I'm a coworker of Alberto.
Certainly, using LogonUser, is not an option. We are looking for a solution
using WindowsIdentity upn ctor.
I've read The .NET Developer's Guide to Windows Security from Keith Brown,
and he writes a chapter about Protocol Transition, but nowhere he mentions
about the need of having Act As Part of Operating System privilege.

Is there any scenario/configuration for this to work?

Let me tell you which is the real problem. Maybe you have an idea on how to
solve this.

* DotNetNuke ASP.NET app.
* The users of this application will be either intranet and extranet users.
If only were intranet users we could use Integrated Security in IIS and
impersonate="true" on ASP.Net and everything would be solved.
* However, we need to give access to extranet users. We enabled Anonymous in
IIS to do that.
* BUT, here is the non-negotiable requirement: the ASP.Net thread MUST run
with the user identity (either intranet user or extranet).
* We give Forms Authentication for extranet users. They login using its upn
and password, we authenticate them against AD and finally we need to
impersonate the thread with the identity of this user.

The scenario is: two domains (forests) with a trust relationship between
them. One domain for intranet users and another for extranet.

So we need a solution that fits this:
* Users from different domains must be able to impersonate its identity for
every request on the ASP.Net app.

Thanks for your help,
Matias
 
J

Joe Kaplan \(MVP - ADSI\)

What I'd suggest is that you put the WindowsIdentity creation code in a COM+
component running under the SYSTEM identity or perhaps another account with
Act As Part of the Operating System and call that from your web code. That
is the most secure approach I can think of to do this.

The other approach is to run your worker process as a similarly powerful
account, but that leaves you more open to vulnerability.

The documentation is here:
http://msdn.microsoft.com/library/d...secauthn/security/lsalogonuser.asp?frame=true

I'm surprised Keith's book doesn't mention that as I was almost positive I
learned this originally from him. Maybe it was an article or blog
posting...

Best of luck,

Joe K.
 

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

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top