Impersonate user from ASP.NET - access to network file share

M

Michelle

Hello!

I have an ASP.NET application (1.1 framework) that needs to be able to
read/write files on a network share. The access to this file share
will be fairly restricted, so I need to impersonate a specific user
account on our domain in order to gain access. The impersonation is
only needed for the sections that reads/writes files. I have tried
using the code from http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q306158#4
and many other similar sources with no success. I do not get any
errors, but I am not logged in using the username and passoword I
provide so I cannot access the network (it remains the anonymous
user). I have tried putting the impersonation code into a Class
Library and calling that from the web application with the same
results.

I must be doing something wrong. Any help would be appreciated.
(see code snippets below - irrelevant code has been removed)

Thank you,
Michelle


** CLASS LIBRARY **
****************************

Imports System.IO
Imports System.String
Imports System.Security.Principal
Imports System.Security



Public Class PerformanceReviewAttachment


Private Shared LOGON32_LOGON_INTERACTIVE As Integer = 2
Private Shared LOGON32_PROVIDER_DEFAULT As Integer = 0
Private Shared impersonationContext As WindowsImpersonationContext

Declare Function LogonUserA Lib "advapi32.dll" (ByVal lpszUsername
As String, _
ByVal lpszDomain As String, _
ByVal lpszPassword As String, _
ByVal dwLogonType As Integer, _
ByVal dwLogonProvider As Integer, _
ByRef phToken As IntPtr) As Integer

Declare Auto Function DuplicateToken Lib "advapi32.dll" ( _
ByVal ExistingTokenHandle As IntPtr, _
ByVal ImpersonationLevel As Integer, _
ByRef DuplicateTokenHandle As IntPtr) As
Integer

Declare Auto Function RevertToSelf Lib "advapi32.dll" () As Long
Declare Auto Function CloseHandle Lib "kernel32.dll" (ByVal handle
As IntPtr) As Long




Shared Function impersonateValidUser(ByVal userName As String,
ByVal domain As String, ByVal password As String) As Boolean
Dim tempWindowsIdentity As WindowsIdentity
Dim token As IntPtr = IntPtr.Zero
Dim tokenDuplicate As IntPtr = IntPtr.Zero
impersonateValidUser = False

If RevertToSelf() <> 0 Then
If LogonUserA(userName, domain, password,
LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, token) <> 0 Then
If DuplicateToken(token, 2, tokenDuplicate) <> 0 Then
tempWindowsIdentity = New
WindowsIdentity(tokenDuplicate)
impersonationContext =
tempWindowsIdentity.Impersonate()
If Not impersonationContext Is Nothing Then
impersonateValidUser = True
End If
End If
End If
End If
If Not tokenDuplicate.Equals(IntPtr.Zero) Then
CloseHandle(tokenDuplicate)
End If
If Not token.Equals(IntPtr.Zero) Then
CloseHandle(token)
End If
End Function

Shared Sub undoImpersonation()
impersonationContext.Undo()
End Sub
End Class




** WEB FORM **
****************************

Private Sub Submit1_ServerClick(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles Submit1.ServerClick
Try

If classLibrary.impersonateValidUser("user",
"domain", "pwd") Then
File1.PostedFile.SaveAs(strFileName)
classLibrary.undoImpersonation()
Else
Throw New ApplicationException("Failed")
End If
Catch Ex As Exception
lblErrorMessage.Text = ex.Message
End Try
End Sub
 
W

Willy Denoyette [MVP]

1.You should not use LOGON32_LOGON_INTERACTIVE, instead you should Call
LogonUser specifying LOGON32_LOGON_NETWORK_CLEARTEXT (8) or
LOGON32_LOGON_NEW_CREDENTIALS (9) as logontype.
2. You should not call DuplicateToken, instead you should use the token
obtained from LogonUser to create the temp WindowsIdentity.

Willy.

PS. LOGON32_LOGON_NEW_CREDENTIALS can only be used by Domain credentials on
a W2K AD domain.
 
M

Michelle

Hi Willy!

Thank you for your reply. I have implemented the changes you
suggested (see snippet below), however LogonA still returns 0. Could
the NT Domain be preventing the logon somehow? I have not adjusted any
security on the web server, could something there be preventing the
logon? I do not get any errors, can I assume that the unmanaged code
is being called properly?

Sorry for all of the questions! Thank you.
Michelle


**********************************
If RevertToSelf() <> 0 Then
If LogonUserA(userName, domain, password,
LOGON32_LOGON_NETWORK_CLEARTEXT, LOGON32_PROVIDER_DEFAULT, token) <> 0
Then
tempWindowsIdentity = New WindowsIdentity(token)
impersonationContext =
tempWindowsIdentity.Impersonate()
If Not impersonationContext Is Nothing Then
impersonationSucceeded = True
End If
End If
End If
**********************************
 
P

Paul Clement

On 8 Dec 2004 11:31:21 -0800, (e-mail address removed) (Michelle) wrote:

¤ Hello!
¤
¤ I have an ASP.NET application (1.1 framework) that needs to be able to
¤ read/write files on a network share. The access to this file share
¤ will be fairly restricted, so I need to impersonate a specific user
¤ account on our domain in order to gain access. The impersonation is
¤ only needed for the sections that reads/writes files. I have tried
¤ using the code from http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q306158#4
¤ and many other similar sources with no success. I do not get any
¤ errors, but I am not logged in using the username and passoword I
¤ provide so I cannot access the network (it remains the anonymous
¤ user). I have tried putting the impersonation code into a Class
¤ Library and calling that from the web application with the same
¤ results.
¤

If you're accessing a resource that is not located on the web server then you will probably need to
implement delegation:

How to configure an ASP.NET application for a delegation scenario
http://support.microsoft.com/default.aspx?scid=kb;en-us;810572


Paul ~~~ (e-mail address removed)
Microsoft MVP (Visual Basic)
 
M

Michelle

Hi Paul,

Thank you for posting that link. I have a question: Impersonation and
delegation do not directly rely on eachother, do they? What I mean is,
I can have impersonation working but not be able to access network
resources because of delegation? If so, then I can wait to implement
the delegation changes recommended in the link until I get
impersonation working (LogonUserA always returns 0)? I ask because I'd
have to clear many of the delegation changes with the sys-admin before
going ahead with them, and that could take a while.

Also, I thought I'd mention as an FYI in case this could help point out
why I have a problem with impersonation: I cannot remove anonymous
access from the web site and have only Integrated authentication. Not
everyone who logs into the application has their own computer or NT
login and some log in from home, so I use a custom authentication that
I built for when they log in. So, on the 1 page only, I need to
impersonate a user on the NT Domain that the sys-admin will create so
that the user has access to the directory on the network where the
files will be saved.

Thanks again!
Michelle
 
W

Willy Denoyette [MVP]

If LogonUser returns <> 0
call Marshal.getLastWin32Error() to retrieve the Win32 error code.

Are you sure you pass a valid user, machine and password as arguments?
Say you are user alice on Alice's machine want to authenticate as user Bob
on BobsMachine, then you need to pass "Bob", "BobsMachine", "BobsPwd".

Willy.
 
M

Michelle

Hi all!!

I just wanted to let you know that I have conceeded and just put
<identity impersonate="true" userName="accountname" password="password"
/> in the web config. This works perfectly. I origionally didnt' want
to set up impersonation for the whole site, but hopefully my sysadmin
will clear it and all will be well.

Thanks!!
Michelle
 
J

John Timney \(ASP.NET MVP\)

You could just move the part of the application that reads and writes files
to its own application space and use impersonation there only.

--
Regards

John Timney
ASP.NET MVP
Microsoft Regional Director
 
P

Paul Clement

On 9 Dec 2004 12:50:39 -0800, (e-mail address removed) wrote:

¤ Hi all!!
¤
¤ I just wanted to let you know that I have conceeded and just put
¤ <identity impersonate="true" userName="accountname" password="password"
¤ /> in the web config. This works perfectly. I origionally didnt' want
¤ to set up impersonation for the whole site, but hopefully my sysadmin
¤ will clear it and all will be well.

That probably works because the user name and password are clear text at the web server and can be
passed in response to authentication challenges from remote resources.

In answer to your other question, delegation is the next step after impersonation when attempting to
access remote resources. If you're using a mechanism where the user ID and password are encrypted
then you need to implement the delegation mechanism w/Kerberos.

If your credentials are clear text at the web server such as in Basic authentication with no SSL
(which of course isn't particularly secure) then those credentials can be used in response to
authentication challenges when access remote resources.

You can find more info at the below link:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetsec/html/SecNetch08.asp


Paul ~~~ (e-mail address removed)
Microsoft MVP (Visual Basic)
 

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

Top