Error casting User.Identity to WindowsIdentity

R

Razak

Hi,

I have a class which basically do Impersonation in my web application. From
MS KB sample:-

++++++++++++++++++++code starts
Dim impersonationContext As
System.Security.Principal.WindowsImpersonationContext
Dim currentWindowsIdentity As System.Security.Principal.WindowsIdentity

currentWindowsIdentity = CType(User.Identity,
System.Security.Principal.WindowsIdentity)
impersonationContext = currentWindowsIdentity.Impersonate()

'Insert your code that runs under the security context of the authenticating
user here.

impersonationContext.Undo()
+++++++++++++++++++++code ends

since I need to implement this code in class.vb, I have to change the line:-

currentWindowsIdentity = CType(User.Identity,
System.Security.Principal.WindowsIdentity)

to:-

currentWindowsIdentity = CType(HttpContext.Current.User.Identity,
System.Security.Principal.WindowsIdentity)

But that produces error 'Specified cast is not valid.'. Is there anything
that I miss here? Please help!

Thank you
 
D

Dale

I am not sure what you're trying to do with impersonation so it's hard to
tell you exactly how to do it but the User object in your web app is
equivelent to a System.Security.Principal.IPrincipal object and not a
WindowsPrincipal object.

Likewise, the User.Identity is an IIdentity and not a WindowsIdenity object.

Can you post more about what you're trying to do?

Dale
 
R

Razak

Sorry for late reply.. I took a day off yesterday.

I'm new to .NET and want to learn by creating my personal website using
ASP.NET and VB.NET. In my application, I have photo galleries where I can
upload photos of certain events (galleries) into a folder in the images
folder. Every events have their own folder to keep the photos. I have no
problem creating folders. But when it comes to deleting them, i got 'Access
denied' which probably because of security issues. I don't want to change
anything on the server side, and resort to using impersonation.

From the samples given by MS KB at
http://support.microsoft.com/default.aspx?scid=kb;EN-US;306158, i have no
problem impersonating as the administrator account (I maintain the server in
the office), that is, the fourth example on the link titled 'Impersonate a
Specific User in Code'. I came across the third example titled 'Impersonate
the Authenticating User in Code', (the code is given in my original post)
and would like to try that method. That's when the error occurs.

Hope that you understand what I'm trying to say here. It's just the purpose
of learning. I believe it should work somehow.

Thanks.
 
D

Dale

Remember that by impersonating a specific user, you have to include username
and password your code. This is not a good idea except in very controlled
environments.

Set Anonymous Access off on the virtual folder in IIS, click Basic
Authentication off, and click Windows Integrated Authentication on.

And, of course, make sure your ACLs are set properly on the files and
folders for the users you want to have access.

Next, in the <system.web> section of your web.config for your web app,
include the following:

<identity impersonate="true" />

Now, your file access will be determined by the windows user from your
domain who is logged in.

You can also customize the access in code by using the
User.Identity.IsInRole("SomeSecurityUserOrGroupName") method - accepting or
rejecting the request based on the results.

Hope this helps,

Dale Preston
MCAD, MCSE, MCDBA


Razak said:
Sorry for late reply.. I took a day off yesterday.

I'm new to .NET and want to learn by creating my personal website using
ASP.NET and VB.NET. In my application, I have photo galleries where I can
upload photos of certain events (galleries) into a folder in the images
folder. Every events have their own folder to keep the photos. I have no
problem creating folders. But when it comes to deleting them, i got 'Access
denied' which probably because of security issues. I don't want to change
anything on the server side, and resort to using impersonation.

From the samples given by MS KB at
http://support.microsoft.com/default.aspx?scid=kb;EN-US;306158, i have no
problem impersonating as the administrator account (I maintain the server in
the office), that is, the fourth example on the link titled 'Impersonate a
Specific User in Code'. I came across the third example titled 'Impersonate
the Authenticating User in Code', (the code is given in my original post)
and would like to try that method. That's when the error occurs.

Hope that you understand what I'm trying to say here. It's just the purpose
of learning. I believe it should work somehow.

Thanks.

-------------------------------------------------------------------------- --
---- --------------------------------------------------------------------- --
---------
Dale said:
I am not sure what you're trying to do with impersonation so it's hard to
tell you exactly how to do it but the User object in your web app is
equivelent to a System.Security.Principal.IPrincipal object and not a
WindowsPrincipal object.

Likewise, the User.Identity is an IIdentity and not a WindowsIdenity object.

Can you post more about what you're trying to do?

Dale

---- ---------------------------------------------------------------------
 
D

Dale

Duh, I don't know what I was thinking.

IsInRole is actually a method of the User object - well, actually the
IPrincipal object upon which the User is based.

Dale

Razak said:
Thanks for the tip. I'll try it tomorrow and see how it goes.

-------------------------------------------------------------------------- --
---- --------------------------------------------------------------------- --
---------
Dale said:
Remember that by impersonating a specific user, you have to include username
and password your code. This is not a good idea except in very controlled
environments.

Set Anonymous Access off on the virtual folder in IIS, click Basic
Authentication off, and click Windows Integrated Authentication on.

And, of course, make sure your ACLs are set properly on the files and
folders for the users you want to have access.

Next, in the <system.web> section of your web.config for your web app,
include the following:

<identity impersonate="true" />

Now, your file access will be determined by the windows user from your
domain who is logged in.

You can also customize the access in code by using the
User.Identity.IsInRole("SomeSecurityUserOrGroupName") method - accepting or
rejecting the request based on the results.

Hope this helps,

Dale Preston
MCAD, MCSE, MCDBA


server
'Impersonate

---- ---------------------------------------------------------------------
-- hard
to
tell you exactly how to do it but the User object in your web app is
equivelent to a System.Security.Principal.IPrincipal object and not a
WindowsPrincipal object.

Likewise, the User.Identity is an IIdentity and not a WindowsIdenity
object.

Can you post more about what you're trying to do?

Dale


Hi,

I have a class which basically do Impersonation in my web application.
From
MS KB sample:-

++++++++++++++++++++code starts
Dim impersonationContext As
System.Security.Principal.WindowsImpersonationContext
Dim currentWindowsIdentity As System.Security.Principal.WindowsIdentity

currentWindowsIdentity = CType(User.Identity,
System.Security.Principal.WindowsIdentity)
impersonationContext = currentWindowsIdentity.Impersonate()

'Insert your code that runs under the security context of the
authenticating
user here.

impersonationContext.Undo()
+++++++++++++++++++++code ends

since I need to implement this code in class.vb, I have to change the
line:-

currentWindowsIdentity = CType(User.Identity,
System.Security.Principal.WindowsIdentity)

to:-

currentWindowsIdentity = CType(HttpContext.Current.User.Identity,
System.Security.Principal.WindowsIdentity)

But that produces error 'Specified cast is not valid.'. Is there
anything
that I miss here? Please help!

Thank you
 
R

Razak

Dale,

Maybe we are a bit off from the main question of my post which was why the
statement:-

currentWindowsIdentity = CType(HttpContext.Current.User.Identity,
System.Security.Principal.WindowsIdentity)

in code-behind produces error while

currentWindowsIdentity = CType(User.Identity,
System.Security.Principal.WindowsIdentity)

in aspx page does not.

----------------------------------------------------------------------------
---- -----------------------------------------------------------------------
---------
Dale said:
Duh, I don't know what I was thinking.

IsInRole is actually a method of the User object - well, actually the
IPrincipal object upon which the User is based.

Dale

Razak said:
Thanks for the tip. I'll try it tomorrow and see how it goes.

--------------------------------------------------------------------------
have
no have
no 'Impersonate

--------------------------------------------------------------------------

---- --------------------------------------------------------------------- not
 
S

Shan Plourde

Could it be related to where you are placing this in both the .aspx and
code behind? As more of an apples to apples comparison, did you code
this within a Page_Load() event handler first in your aspx page, then in
your code behind? Or, did you place them in different methods
altogether? If so, first start by ensuring that you have that apples to
apples comparison.

Otherwise, it is likely that the current user property is not yet set by
the .NET presentation framework depending on where you are trying to
access it from within your code behind. That would be my first guess.
The MSDN may have some tips on when this property is set. You may want
to look up HttpApplication and see if your code behind logic is getting
accessed after the appropriate HttpApplication AuthenticateRequest event
has been fired (or AuthorizeRequest)...

Also, ensure that you have System.Web in your using list in your code
behind. Hopefully that helps

Shan Plourde
 
R

Razak

Sorry for the lack of information. What I did in my code is like from an
aspx page Save button clck event, I called a shared method AddNew of a
class, declared in PhotoGalleryUtility.vb. In that method, I did the saving
of gallery data into an SQL db. Then I call a private method in the same
class called CreateDir. There is where I put the code to create a folder for
the newly added gallery data. The folder is created inside
webroot/images/galleries/{0} where {0} is the galleryID in the database. I
do not need to do anything in terms of security here. The folder will be
created at the specified location on the server just fine.

Ok, that's the first part. My app also allows gallery deletion, which,
deletes gallery entry in the database, and also the corresponding folder in
the said location.

From the aspx page listing all available galleries, and every each of them
have their 'X' image button to initiate deletion process. Clicking this
image, will trigger the javascript 'yes/no' confirmation alert box, then
calls the datagrid_ItemCommand event. From there, i call Delete method in
the same class as above. (PhotoGalleryUtility.vb). In that method, I delete
the entry from the db, proceed to deleting the corresponding folder in the
location. The delete code is actually in different private method in the
class (DeleteDir), so here is the method:-

' *********************************************************************
' DeleteDir Methods (private)
' *********************************************************************
'
' Create directory in images folder.
'
' *********************************************************************
Private Shared Sub DeleteDir(ByVal gallery_id As Integer)
' Specify the directory you want to manipulate.
Dim path As String =
HttpContext.Current.Server.MapPath(String.Format("../{0}/{1}",
ABGGlobals.GalleriesPath, gallery_id))

' Determine whether the directory exists.
If Directory.Exists(path) Then
Dim imp As New ImpersonateUser
If imp.LogSelf() Then
' Delete the directory.
Directory.Delete(path, True)
imp.LogOff()
Else
Throw New Exception("Impersonation failed!")
End If
Else
Throw New Exception("Directory does not exist!")
End If
End Sub
'*********************************************************************
OK, here's my ImpersonateUser class, defined in ImpersonateUser.vb:-

'*********************************************************************
Imports System.Security.Principal
Imports System.Runtime.InteropServices

Public Class ImpersonateUser
Private _impersonationContext As WindowsImpersonationContext
Private Declare Function LogonUserA Lib "advapi32.dll" (ByVal
lpszUsername As String, _ ......................
Private Declare Auto Function DuplicateToken Lib "advapi32.dll" ( _
......................
Private Declare Auto Function RevertToSelf Lib "advapi32.dll" () As Long
Private Declare Auto Function CloseHandle Lib "kernel32.dll" (ByVal
handle As IntPtr) As Long

' *********************************************************************
' LogSelf Methods
' *********************************************************************
'
' Log current user.
'
' *********************************************************************
Public Function LogSelf() As Boolean
Dim currentWindowsIdentity As WindowsIdentity

HttpContext.Current.Session("name") = ""
HttpContext.Current.Session("test") = ""
currentWindowsIdentity = CType(HttpContext.Current.User.Identity,
WindowsIdentity) <============== The problematic line!
HttpContext.Current.Session("name") = currentWindowsIdentity.Name()
HttpContext.Current.Session("test") = "Session OK"
If currentWindowsIdentity.IsAuthenticated Then
_impersonationContext = currentWindowsIdentity.Impersonate()
Return True
Else
Return False
End If
End Function

' *********************************************************************
' LogOff Methods
' *********************************************************************
'
' Revert impersonation.
'
' *********************************************************************
Public Sub LogOff()
_impersonationContext.Undo()
End Sub
End Class
'*********************************************************************

I have tried passing the identity object from code behind of the aspx page
to the impersonateuser class so that i can skip the 'currentWindowsIdentity
= CType(HttpContext.Current.User.Identity, WindowsIdentity)' line all
together in the class. But in code behind file, the casting in line X :

'*********************************************************************
Private Sub dgrdGalleries_ItemCommand(ByVal source As Object, ByVal e As
System.Web.UI.WebControls.DataGridCommandEventArgs) Handles
dgrdGalleries.ItemCommand
Dim galleryID As Integer =
Fix(dgrdGalleries.DataKeys(e.Item.ItemIndex))
Select Case e.CommandName
Case "Delete"
lblError.Text = PhotoGalleryUtility.Delete(galleryID,
CType(HttpContext.Current.User.Identity,
System.Security.Principal.WindowsIdentity)) <=== X!!
Case "Up"
PhotoGalleryUtility.MoveUp(galleryID)
Case "Down"
PhotoGalleryUtility.MoveDown(galleryID)
End Select
End Sub
'*********************************************************************

keep producing the error:-

Server Error in '/' Application.
Specified cast is not valid.
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.InvalidCastException: Specified cast is not valid.

This a lengthy post, and I'm tired of this casting error and thinking of
giving up this impersonation method... prefer the impersonate as specified
user/pwd/domain method anyway...


----------------------------------------------------------------------------
---- -----------------------------------------------------------------------
---------
Shan Plourde said:
Could it be related to where you are placing this in both the .aspx and
code behind? As more of an apples to apples comparison, did you code
this within a Page_Load() event handler first in your aspx page, then in
your code behind? Or, did you place them in different methods
altogether? If so, first start by ensuring that you have that apples to
apples comparison.

Otherwise, it is likely that the current user property is not yet set by
the .NET presentation framework depending on where you are trying to
access it from within your code behind. That would be my first guess.
The MSDN may have some tips on when this property is set. You may want
to look up HttpApplication and see if your code behind logic is getting
accessed after the appropriate HttpApplication AuthenticateRequest event
has been fired (or AuthorizeRequest)...

Also, ensure that you have System.Web in your using list in your code
behind. Hopefully that helps

Shan Plourde
Dale,

Maybe we are a bit off from the main question of my post which was why the
statement:-

currentWindowsIdentity = CType(HttpContext.Current.User.Identity,
System.Security.Principal.WindowsIdentity)

in code-behind produces error while

currentWindowsIdentity = CType(User.Identity,
System.Security.Principal.WindowsIdentity)

in aspx page does not.

---------------------------------------------------------------------------
-

---- ---------------------------------------------------------------------- -
---------

Duh, I don't know what I was thinking.

IsInRole is actually a method of the User object - well, actually the
IPrincipal object upon which the User is based.

Dale



Thanks for the tip. I'll try it tomorrow and see how it goes.
--------------------------------------------------------------------------

---- ---------------------------------------------------------------------
--


---------


Remember that by impersonating a specific user, you have to include


username


and password your code. This is not a good idea except in very


controlled


environments.

Set Anonymous Access off on the virtual folder in IIS, click Basic
Authentication off, and click Windows Integrated Authentication on.

And, of course, make sure your ACLs are set properly on the files and
folders for the users you want to have access.

Next, in the <system.web> section of your web.config for your web app,
include the following:

<identity impersonate="true" />

Now, your file access will be determined by the windows user from your
domain who is logged in.

You can also customize the access in code by using the
User.Identity.IsInRole("SomeSecurityUserOrGroupName") method -

accepting


or


rejecting the request based on the results.

Hope this helps,

Dale Preston
MCAD, MCSE, MCDBA




Sorry for late reply.. I took a day off yesterday.

I'm new to .NET and want to learn by creating my personal website


using


ASP.NET and VB.NET. In my application, I have photo galleries where

I


can


upload photos of certain events (galleries) into a folder in the


images


folder. Every events have their own folder to keep the photos. I

have


no


problem creating folders. But when it comes to deleting them, i got


'Access


denied' which probably because of security issues. I don't want to


change


anything on the server side, and resort to using impersonation.

From the samples given by MS KB at
http://support.microsoft.com/default.aspx?scid=kb;EN-US;306158, i

have


no


problem impersonating as the administrator account (I maintain the


server


in


the office), that is, the fourth example on the link titled


'Impersonate


a


Specific User in Code'. I came across the third example titled


'Impersonate


the Authenticating User in Code', (the code is given in my original


post)


and would like to try that method. That's when the error occurs.

Hope that you understand what I'm trying to say here. It's just the


purpose


of learning. I believe it should work somehow.

Thanks.
--------------------------------------------------------------------------

---- ---------------------------------------------------------------------
--


---------


I am not sure what you're trying to do with impersonation so it's


hard


to


tell you exactly how to do it but the User object in your web app

is


equivelent to a System.Security.Principal.IPrincipal object and

not


a


WindowsPrincipal object.

Likewise, the User.Identity is an IIdentity and not a

WindowsIdenity


object.


Can you post more about what you're trying to do?

Dale




Hi,

I have a class which basically do Impersonation in my web


application.


From


MS KB sample:-

++++++++++++++++++++code starts
Dim impersonationContext As
System.Security.Principal.WindowsImpersonationContext
Dim currentWindowsIdentity As


System.Security.Principal.WindowsIdentity


currentWindowsIdentity = CType(User.Identity,
System.Security.Principal.WindowsIdentity)
impersonationContext = currentWindowsIdentity.Impersonate()

'Insert your code that runs under the security context of the


authenticating


user here.

impersonationContext.Undo()
+++++++++++++++++++++code ends

since I need to implement this code in class.vb, I have to

change


the


line:-


currentWindowsIdentity = CType(User.Identity,
System.Security.Principal.WindowsIdentity)

to:-

currentWindowsIdentity =

CType(HttpContext.Current.User.Identity,


System.Security.Principal.WindowsIdentity)

But that produces error 'Specified cast is not valid.'. Is there


anything


that I miss here? Please help!

Thank you
--------------------------------------------------------------------------

---- ---------------------------------------------------------------------
 

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,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top