If Not IsPostBack Then
Dim bUseWindowsAuthentication As Boolean = Application("UseWindowsAuthentication")
If bUseWindowsAuthentication Then
' Redirect to winlogin to try WindowsAuthentication if possible
'http://aspadvice.com/blogs/rjdudley/archive/2005/03/10/2561.aspx
'http://aspadvice.com/blogs/rjdudley/archive/2005/03/10/2562.aspx (How I Made Windows Authentication and Forms Authentication Work Together )
'//only try to force windows if starting with LAN ip address
'//change this logic as your like using a Regex
Dim r As New Regex(ConfigurationSettings.AppSettings("lanIPmask"))
If r.IsMatch(Me.Request.UserHostAddress) = True Or HttpRequestHelper.IsBrowserOnServer Then
If Me.Request.QueryString("WinLoginError") = Nothing Then 'avoid indefinite loop
Dim sQueryString As String = Me.Request.QueryString.ToString()
DebugHelper.TracedLine("sQueryString =" & sQueryString)
Response.Redirect("Authent/WinLogin.aspx?" & sQueryString)
Else
lblError.Text = Me.Request.QueryString("WinLoginError")
End If
End If
End If
The snippet from Authent/WinLogin.aspx page
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspp/html/MixedSecurity.asp
DebugHelper.PrintAspNetIdentities()
Dim userName As String = Me.Request.ServerVariables("LOGON_USER") 'usually with domain name
userName = StringHelper.RightAfter(userName, "\") 'Strip domain if applicable
CreateFormsAuthenticationTicket(userName)
End Sub
Function CreateFormsAuthenticationTicket(ByVal userIdentity As String) As Boolean
Dim oLogin As New FSWeb.LoginHelper
Dim bPersistCookie As Boolean = False ' = Persist.Checked
'Set Current.Session["PatronID"] if successful
Dim bRet As Boolean = False
If Not DataHelper.IsNullOrEmpty(userIdentity) Then
bRet = oLogin.LoadUserFromDatabase(userIdentity)
End If
If bRet = True Then
'Save WindowsIdentity -from http://weblogs.asp.net/pwilson/archive/2004/02/02/66155.aspx
Dim sUserToken As String = LoginHelper.GetUserTokenAsString(Me.Context)
Dim userToken As New IntPtr(Integer.Parse(sUserToken))
Dim identity As New WindowsIdentity(userToken, "NTLM", WindowsAccountType.Normal, True)
Dim principal1 As New WindowsPrincipal(identity)
bRet = oLogin.SaveWindowsPrincipalInSession(principal1)
End If
If bRet = True Then
oLogin.CreateTicket()
If FSWeb.Login.RedirectBack(Me) = True Then Exit Function 'old way of redirect
' Redirect back to original URL.
WebFormsHelper.SmartRedirect(Page, FormsAuthentication.GetRedirectUrl(oLogin.PatronID, bPersistCookie))
Else 'windows account not found in the database- so use normal forms authentication
Dim sQueryString As String = HttpHelper.QueryStringCollectionToString(Me.Request.QueryString)
'Expected that oLogin.ErrorMessage is meaningful, but if not, ensure it's not empty
sQueryString = HttpHelper.AddQueryStringParameter(sQueryString, "WinLoginError", Nz(oLogin.ErrorMessage, "Error during windows Authentication"))
Dim sUrl As String = ResolveUrl("~\login.aspx?" & sQueryString)
WebFormsHelper.SmartRedirect(Page, sUrl)
End If
Return bRet
End Function
To setup this functionality it is required to specify lanIPmask in Web.Config and set authentication on Authent\WinLogin.aspx page to be Windows Integrated only.
Procedure to specify lanIPmask:
- Open file web.config in your web application folder the text editor(e.g. Notepad)
- Search for a line
<add key="lanIPmask" value=""/>
- Change the value to appropriate, e.g. "192.168.\d{1,3}\.\d{1,3}" if your LAN IP addresses are in range "192.168.0.0"- "192.168.255.255"
For details how mask can be specified see
http://www.regular-expressions.info/examples.html
- Save the changed file.
Procedure to set Authent\WinLogin.aspx page to be Windows Integrated only.
1. On the web server right-click the My Computer icon and click Manage.
2. Expand the Services and Applications node in the MMC.
3. Select Internet Information Services.
- Navigate to YorApplicationVirtualDirectory\Authent Folder(Assume that the application is installed in the default virtual folder).
- Right-mouse click WinLogin.aspx, then Click Properties, and then click the File Security tab.
- Under Authentication and access control, click Edit.
- In the Enable Anonymous Access group, clear the Enable anonymous access check box.
- Ensure that Integrated Windows Authentication check box is ticked
- Click OK to close the dialog.
UPDATE- See the post Programmatically set IIS Authentication for a page. to set authentication for WinLogin.aspx automatically from the installer.
It is also required to change Internet Explorer clients setting to trust your website as described at
http://groups.google.com.au/group/microsoft.public.inetserver.iis/msg/4e6c0dda9313f23a?hl=en&
I want to highlight that site should be added to Local Intranet , not to Trusted Sites.
UPDATE: requested to post code of helper classes that are referred by these snippets.
See My DataHelper class. (including Nz method), My DebugHelper and TraceHelper classes, My HttpRequestHelper class, My StringHelper class.
To resolve 'WindowsIdentity' and 'WindowsPrincipal' add
imports System.Security.Principal.
FSWeb.LoginHelper, FSWeb.Login and HttpHelper classes contain propriatary information and can't be published. You should replace them with your own code.
UPDATE: there is excellent Michael Morozov's post Single Sign-On for everyone ,which suggest easier solution for mixed-mode authentication (Forms and Windows).I haven't tried, but it looks promising.