Solved

Windows Authentication with an initial splash page without authentification

Posted on 2010-09-03
3
624 Views
Last Modified: 2012-06-21
Hi all, We want to use Windows Authentication  but need to be able to go to a splash screen where the user chooses their language preference before going to the logon screen.  How do we delay authenfication until after the user get s to their logon screen?

Below is all the applicable related to Windows Authentication from web.config, Global.asax, the logon page and the LDAP class

Any help is appreciated,

<authentication mode="Forms">
      <forms loginUrl="/Web/Default-Default.aspx" name="adAuthCookie" timeout="60" path="/" >
      </forms>
    </authentication>
    <authorization>
      <deny users="?" />
      <allow users="*" />
    </authorization>
    <identity impersonate="true" />  


Global.asax

Sub Application_AuthenticateRequest(ByVal sender As Object, ByVal e As EventArgs)
        ' Fires upon attempting to authenticate the use
        Dim cookieName As String = FormsAuthentication.FormsCookieName
        Dim authCookie As HttpCookie = Context.Request.Cookies(cookieName)

        If (authCookie Is Nothing) Then
            'There is no authentication cookie.
            Return
        End If

        Dim authTicket As FormsAuthenticationTicket = Nothing

        Try
            authTicket = FormsAuthentication.Decrypt(authCookie.Value)
        Catch ex As Exception
            'Write the exception to the Event Log.
            Return
        End Try

        If (authTicket Is Nothing) Then
            'Cookie failed to decrypt.
            Return
        End If

        'When the ticket was created, the UserData property was assigned a
        'pipe-delimited string of group names.
        Dim groups As String() = authTicket.UserData.Split(New Char() {"|"})

        'Create an Identity.
        Dim id As GenericIdentity = New GenericIdentity(authTicket.Name, "LdapAuthentication")

        'This principal flows throughout the request.
        Dim principal As GenericPrincipal = New GenericPrincipal(id, groups)

        Context.User = principal

    End Sub


Logon

             Sub Login_Click(ByVal sender As Object, ByVal e As EventArgs)
        Dim adPath As String = "LDAP://ncr.ec.gc.ca" 'Path to your LDAP directory server
              Dim adAuth As LdapAuthentication = New LdapAuthentication(adPath)
                 Try
                     If (True = adAuth.IsAuthenticated(txtDomain.Text, txtUsername.Text, txtPassword.Text)) Then
                         Dim groups As String = adAuth.GetGroups()
      
                         'Create the ticket, and add the groups.
                'Dim isCookiePersistent As Boolean = chkPersist.Checked
                Dim authTicket As FormsAuthenticationTicket = New FormsAuthenticationTicket(1, _
                    txtUserName.Text, DateTime.Now, DateTime.Now.AddMinutes(60), False, groups)
            
                         'Encrypt the ticket.
                         Dim encryptedTicket As String = FormsAuthentication.Encrypt(authTicket)
                  
                         'Create a cookie, and then add the encrypted ticket to the cookie as data.
                         Dim authCookie As HttpCookie = New HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket)
      
                'If (isCookiePersistent = True) Then
                '    authCookie.Expires = authTicket.Expiration
                'End If
                         'Add the cookie to the outgoing cookies collection.
                         Response.Cookies.Add(authCookie)
      
                         'You can redirect now.
                         Response.Redirect(FormsAuthentication.GetRedirectUrl(txtUsername.Text, False))
          
                     Else
                         errorLabel.Text = "Authentication did not succeed. Check user name and password."
                     End If
      
                 Catch ex As Exception
                     errorLabel.Text = "Error authenticating. " & ex.Message
                 End Try
             End Sub

LdapAuthenticate

Imports System
Imports System.Text
Imports System.Collections
Imports System.DirectoryServices
Namespace FormsAuth
    Public Class LdapAuthentication

        Dim _path As String
        Dim _filterAttribute As String

        Public Sub New(ByVal path As String)
            _path = path
        End Sub

        Public Function IsAuthenticated(ByVal domain As String, ByVal username As String, ByVal pwd As String) As Boolean

            Dim domainAndUsername As String = domain & "\" & username
            Dim entry As DirectoryEntry = New DirectoryEntry(_path, domainAndUsername, pwd)

            Try
                'Bind to the native AdsObject to force authentication.                  
                Dim obj As Object = entry.NativeObject
                Dim search As DirectorySearcher = New DirectorySearcher(entry)

                search.Filter = "(SAMAccountName=" & username & ")"
                search.PropertiesToLoad.Add("cn")
                Dim result As SearchResult = search.FindOne()

                If (result Is Nothing) Then
                    Return False
                End If

                'Update the new path to the user in the directory.
                _path = result.Path
                _filterAttribute = CType(result.Properties("cn")(0), String)

            Catch ex As Exception
                Throw New Exception("Error authenticating user. " & ex.Message)
            End Try

            Return True
        End Function

        Public Function GetGroups() As String
            Dim search As DirectorySearcher = New DirectorySearcher(_path)
            search.Filter = "(cn=" & _filterAttribute & ")"
            search.PropertiesToLoad.Add("memberOf")
            Dim groupNames As StringBuilder = New StringBuilder()

            Try
                Dim result As SearchResult = search.FindOne()
                Dim propertyCount As Integer = result.Properties("memberOf").Count

                Dim dn As String
                Dim equalsIndex, commaIndex

                Dim propertyCounter As Integer

                For propertyCounter = 0 To propertyCount - 1
                    dn = CType(result.Properties("memberOf")(propertyCounter), String)

                    equalsIndex = dn.IndexOf("=", 1)
                    commaIndex = dn.IndexOf(",", 1)
                    If (equalsIndex = -1) Then
                        Return Nothing
                    End If

                    groupNames.Append(dn.Substring((equalsIndex + 1), (commaIndex - equalsIndex) - 1))
                    groupNames.Append("|")
                Next

            Catch ex As Exception
                Throw New Exception("Error obtaining group names. " & ex.Message)
            End Try

            Return groupNames.ToString()
        End Function
    End Class
End Namespace



0
Comment
Question by:Mosquitoe
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
3 Comments
 

Author Comment

by:Mosquitoe
ID: 33598940
Nobody has any ideas or comments??  
0
 
LVL 51

Accepted Solution

by:
Ted Bouskill earned 500 total points
ID: 33601940
OK so you are using 'Form Based Authentication' with LDAP as an authentication provider.

In order to understand how difficult this is to solve I need to review how a web application works.  Because a web application is stateless by default IIS doesn't know if you are asking for a web page the first time, second time et cetera.  It literally takes the page request, verifies you have access then sends the page.

If you are using Windows Authentication then I would stop using "Form Based Authentication", turn off anonymous authentication and select "Integrated Windows Authentication" then do the following work flow.

1) When a page is requested (any page) look for a cookie that defines the language.  You can use the Session_Start event in the global.asax or create a base page that is used as a base class for all you other pages
2) If it doesn't exist, store the current page request in a session variable and redirect to the page to select a language
3) Show the language selection page, the store the result in a cookie and redirect back to the original page using the session variable.

I've used a database to store this information as well.  Remember with 'Integrated Windows Authentication' you can get the user's identity using: System.Security.Pricipal.WindowsIdentity.GetCurrent()

Using 'Form Based Authentication' is rarely necessary if you are using Windows Authentication.  It blocks internal search engines like Sharepoint and adds unnecessary overhead plus adds the risk of someones password being stolen if you don't use SSL.
0
 

Author Closing Comment

by:Mosquitoe
ID: 33639851
Sorry it took so long to respond to this - thank you for your suggestions; we did end up going to DB with username and password
0

Featured Post

Resolve Critical IT Incidents Fast

If your data, services or processes become compromised, your organization can suffer damage in just minutes and how fast you communicate during a major IT incident is everything. Learn how to immediately identify incidents & best practices to resolve them quickly and effectively.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A phishing scam that claims a recipient’s credit card details have been “suspended” is the latest trend in spoof emails.
Had a business requirement to store the mobile number in an environmental variable. This is just a quick article on how this was done.
Microsoft Active Directory, the widely used IT infrastructure, is known for its high risk of credential theft. The best way to test your Active Directory’s vulnerabilities to pass-the-ticket, pass-the-hash, privilege escalation, and malware attacks …
This video shows how to use Hyena, from SystemTools Software, to bulk import 100 user accounts from an external text file. View in 1080p for best video quality.

752 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question