I
Iain Mcleod
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
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