mixed authentication and LogonUser token in forms ticket - safe?

  • Thread starter Thread starter Iain Mcleod
  • Start date Start date
I

Iain Mcleod

Guest
Hi

I've implemented a mixed forms/windows authentication solution loosely based
on the following example:
http://www.gotdotnet.com/Community/...mpleGuid=a12e9f53-695f-452f-87d0-abbe9f12351e

- an overview of this is as follows:
IIS has anonymous access enabled and also has windows integrated
authentication enabled
my web.config has forms authentication on and impersonation off
In my global.asax.vb I handle FormsAuthentication_Authenticate and if the
user is authenticated via windows auth on the browser's user, I construct a
windows principal for the forms authentication to use based on the following
windows identity:
Dim ident as WindowsIdentity = New WindowsIdentity(request.GetUserToken(),
authType, WindowsAccountType.Normal, True)


If the windows authentication fails, the user is kicked to forms
authentication and must sign in. I validate their password against the
domain via a Win32 call to LogonUser(). The result of this is an IntPtr to a
user handle if supplied credentials are valid. I call CloseHandle() on this
and return the IntPtr, which I then stick in the forms cookie's user data:

' COM interop functions
Private Declare Auto Function LogonUser 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 Boolean
Private Declare Auto Function CloseHandle Lib "kernel32.dll" (ByRef
handle As IntPtr) As Boolean

' COM constants
Private Const InteractiveLogon As Integer = 2
Private Const DefaultProvider As Integer = 0

Public Shared Function AuthenticateAgainstDomain(ByVal domain As String,
ByVal username As String, ByVal password As String) As IntPtr
'
Dim handle As IntPtr = IntPtr.Zero
Dim logonSucceeded As Boolean = LogonUser(username, domain,
password, InteractiveLogon, DefaultProvider, handle)
If Not logonSucceeded Then
Dim errorCode As Integer = Marshal.GetLastWin32Error()
LogException(ExceptionType.AuthenticationError,
String.Format("Unable to logon user. Error code {0}.", errorCode))
End If
CloseHandle(handle)
Return handle
End Function

When the forms ticket is presented by an authenticated user during
Application_AuthenticateRequest event, I extract the IntPtr user token and
construct a windows identity from it:
Dim authcookie As HttpCookie =
Request.Cookies(FormsAuthentication.FormsCookieName)
Dim ticket As FormsAuthenticationTicket =
FormsAuthentication.Decrypt(authcookie.Value)
Dim token As IntPtr = New IntPtr(Integer.Parse(ticket.UserData))
Dim ident as WindowsIdentity = New WindowsIdentity(token, "NTLM",
WindowsAccountType.Normal, True)

My question is this:
obviously, this works in my test environment but is this safe in production?
Can the IntPtr handle be relied on or will it be released at some
unspecified point in the future?

Regards
Iain
 
Looks pretty secure to me (assuming SSL for forms authentication in
place)... Do you have concern about something in particular?

--
Svyatoslav Pidgorny, MS MVP - Security, MCSE
-= F1 is the key =-

* http://sl.mvps.org * http://msmvps.com/blogs/sp *

"Iain Mcleod" <Iain Mcleod@discussions.microsoft.com> wrote in message
news:6994170E-35F5-4468-9C2A-C8ABEA6E8DC1@microsoft.com...
> Hi
>
> I've implemented a mixed forms/windows authentication solution loosely
> based
> on the following example:
> http://www.gotdotnet.com/Community/...mpleGuid=a12e9f53-695f-452f-87d0-abbe9f12351e
>
> - an overview of this is as follows:
> IIS has anonymous access enabled and also has windows integrated
> authentication enabled
> my web.config has forms authentication on and impersonation off
> In my global.asax.vb I handle FormsAuthentication_Authenticate and if the
> user is authenticated via windows auth on the browser's user, I construct
> a
> windows principal for the forms authentication to use based on the
> following
> windows identity:
> Dim ident as WindowsIdentity = New WindowsIdentity(request.GetUserToken(),
> authType, WindowsAccountType.Normal, True)
>
>
> If the windows authentication fails, the user is kicked to forms
> authentication and must sign in. I validate their password against the
> domain via a Win32 call to LogonUser(). The result of this is an IntPtr
> to a
> user handle if supplied credentials are valid. I call CloseHandle() on
> this
> and return the IntPtr, which I then stick in the forms cookie's user data:
>
> ' COM interop functions
> Private Declare Auto Function LogonUser 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 Boolean
> Private Declare Auto Function CloseHandle Lib "kernel32.dll" (ByRef
> handle As IntPtr) As Boolean
>
> ' COM constants
> Private Const InteractiveLogon As Integer = 2
> Private Const DefaultProvider As Integer = 0
>
> Public Shared Function AuthenticateAgainstDomain(ByVal domain As
> String,
> ByVal username As String, ByVal password As String) As IntPtr
> '
> Dim handle As IntPtr = IntPtr.Zero
> Dim logonSucceeded As Boolean = LogonUser(username, domain,
> password, InteractiveLogon, DefaultProvider, handle)
> If Not logonSucceeded Then
> Dim errorCode As Integer = Marshal.GetLastWin32Error()
> LogException(ExceptionType.AuthenticationError,
> String.Format("Unable to logon user. Error code {0}.", errorCode))
> End If
> CloseHandle(handle)
> Return handle
> End Function
>
> When the forms ticket is presented by an authenticated user during
> Application_AuthenticateRequest event, I extract the IntPtr user token and
> construct a windows identity from it:
> Dim authcookie As HttpCookie =
> Request.Cookies(FormsAuthentication.FormsCookieName)
> Dim ticket As FormsAuthenticationTicket =
> FormsAuthentication.Decrypt(authcookie.Value)
> Dim token As IntPtr = New IntPtr(Integer.Parse(ticket.UserData))
> Dim ident as WindowsIdentity = New WindowsIdentity(token, "NTLM",
> WindowsAccountType.Normal, True)
>
> My question is this:
> obviously, this works in my test environment but is this safe in
> production?
> Can the IntPtr handle be relied on or will it be released at some
> unspecified point in the future?
>
> Regards
> Iain
>
>
 
Re: mixed authentication and LogonUser token in forms ticket - saf

Hi

Sorry for delay in responding.

Yes, there is a particular concern. I'm worried that the intptr that I use
within the forms token is a handle on a user object that will be destroyed at
some unspecified time in the future. Because it's web based, the forms
authentication ticket containing the intptr to reconstruct the user identity
can be presented again and again and I don't fully understand what the intptr
actually is. Is it a pointer to the memory location containing the user
object that I created by doing the COM call? Because if it is, I destroy
this with CloseHandle() but it may be lingering around in memory on my dev
machine.

Does that make sense?

Cheers
Iain

"S. Pidgorny <MVP>" wrote:

> Looks pretty secure to me (assuming SSL for forms authentication in
> place)... Do you have concern about something in particular?
>
> --
> Svyatoslav Pidgorny, MS MVP - Security, MCSE
> -= F1 is the key =-
>
> * http://sl.mvps.org * http://msmvps.com/blogs/sp *
>
> "Iain Mcleod" <Iain Mcleod@discussions.microsoft.com> wrote in message
> news:6994170E-35F5-4468-9C2A-C8ABEA6E8DC1@microsoft.com...
> > Hi
> >
> > I've implemented a mixed forms/windows authentication solution loosely
> > based
> > on the following example:
> > http://www.gotdotnet.com/Community/...mpleGuid=a12e9f53-695f-452f-87d0-abbe9f12351e
> >
> > - an overview of this is as follows:
> > IIS has anonymous access enabled and also has windows integrated
> > authentication enabled
> > my web.config has forms authentication on and impersonation off
> > In my global.asax.vb I handle FormsAuthentication_Authenticate and if the
> > user is authenticated via windows auth on the browser's user, I construct
> > a
> > windows principal for the forms authentication to use based on the
> > following
> > windows identity:
> > Dim ident as WindowsIdentity = New WindowsIdentity(request.GetUserToken(),
> > authType, WindowsAccountType.Normal, True)
> >
> >
> > If the windows authentication fails, the user is kicked to forms
> > authentication and must sign in. I validate their password against the
> > domain via a Win32 call to LogonUser(). The result of this is an IntPtr
> > to a
> > user handle if supplied credentials are valid. I call CloseHandle() on
> > this
> > and return the IntPtr, which I then stick in the forms cookie's user data:
> >
> > ' COM interop functions
> > Private Declare Auto Function LogonUser 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 Boolean
> > Private Declare Auto Function CloseHandle Lib "kernel32.dll" (ByRef
> > handle As IntPtr) As Boolean
> >
> > ' COM constants
> > Private Const InteractiveLogon As Integer = 2
> > Private Const DefaultProvider As Integer = 0
> >
> > Public Shared Function AuthenticateAgainstDomain(ByVal domain As
> > String,
> > ByVal username As String, ByVal password As String) As IntPtr
> > '
> > Dim handle As IntPtr = IntPtr.Zero
> > Dim logonSucceeded As Boolean = LogonUser(username, domain,
> > password, InteractiveLogon, DefaultProvider, handle)
> > If Not logonSucceeded Then
> > Dim errorCode As Integer = Marshal.GetLastWin32Error()
> > LogException(ExceptionType.AuthenticationError,
> > String.Format("Unable to logon user. Error code {0}.", errorCode))
> > End If
> > CloseHandle(handle)
> > Return handle
> > End Function
> >
> > When the forms ticket is presented by an authenticated user during
> > Application_AuthenticateRequest event, I extract the IntPtr user token and
> > construct a windows identity from it:
> > Dim authcookie As HttpCookie =
> > Request.Cookies(FormsAuthentication.FormsCookieName)
> > Dim ticket As FormsAuthenticationTicket =
> > FormsAuthentication.Decrypt(authcookie.Value)
> > Dim token As IntPtr = New IntPtr(Integer.Parse(ticket.UserData))
> > Dim ident as WindowsIdentity = New WindowsIdentity(token, "NTLM",
> > WindowsAccountType.Normal, True)
> >
> > My question is this:
> > obviously, this works in my test environment but is this safe in
> > production?
> > Can the IntPtr handle be relied on or will it be released at some
> > unspecified point in the future?
> >
> > Regards
> > Iain
> >
> >

>
>
>
 
Back
Top