Page #43 (Chapter 5 - Securing an IIS Application)

Chapter 5 - Securing an IIS Application

Visual Basic Developers Guide to ASP and IIS
A. Russell Jones
  Copyright 1999 SYBEX Inc.

Add a Custom WebItem
This time, instead of creating an HTML template, you'll create a custom Web-Item, so you'll become familiar with the difference between the two. Right-click the Custom WebItems entry in the WebClass Designer window and select Add Custom WebItem from the pop-up menu. Rename the new item Register, then right-click it again and select View Code.
The WebClass will create a new subroutine stub called Register_Respond. The WebClass calls the respond event on a WebItem when you set the WebClass Next-Item property to that item.
You'll need to add a Registration button to the Signon template so users can reach your registration screen. To modify the Signon template, right-click the Signon WebItem and select Edit HTML Template. VB will launch your default HTML editor.
  Tip To modify the editor that VB uses for editing HTML, click Tools Options, then click the Advanced tab. Enter the path to the editor you want to use in the External HTML Editor field, then click OK.
Change the last row in the table so it contains two buttons instead of one:
' Before
<tr>
    <td align="middle" colspan="2">
            <input type="submit" value="Sign On">
    </td>
</tr>
' After
<tr>
    <td align="middle" colspan="2">
        <input type="submit" name="submit" value="Sign On"> 
        <input type="submit" name="submit" value="Register">
    </td>
</tr>
Notice that the name of both buttons is Submit. That way, you can easily add a check in the Signon_frmSignon event code to determine which button the user clicked. If the user is trying to register, you can reroute them to the Registration screen. Add the following code immediately after the line action = Request .Form("Submit") in the Signon_frmSignon event code.
If action = "Register" Then
     Set NextItem = Register
     Exit Sub
End if
When the code executes, setting the NextItem property to Register fires the Register_Respond event for the Register custom WebItem. In the Register_ Respond event, you'll return the HTML to show the Registration screen. Listing 5.2 shows the HTML for the Registration screen. Place this code in the Register_ Respond event stub.
Listing 5.2: HTML for Registration Screen (in Signon.dsr)
Private Sub Register_Respond()
Dim s As String
Dim sBody As String
      s = getHTMLTemplate()
      s = Replace(s, "<!—Title—>", "SecuredSite Registration")
sBody = "<form name=""frmRegister"" action=""" & _
    URLFor("Register", "register") & """ method=""post"">"
sBody = sBody & "<table align=""center"" width=""60%""" & _
    "cols=""2"" border=""1"">"
sBody = sBody & "<tr><td align=""left"" colspan=""2"">" & _
    "Enter a signon and password. Your signon and " & _
    "password may be up to 20 characters (numbers, " & _
    "letters and symbols), and may not contain spaces. " _
    & "You must enter both a signon and password to " & _
    "register.</td></tr>"
If Session("msg") <> "" Then
    sBody = sBody & "<tr><td align=""left""" & _
    "colspan=""2""><font color=""#FF0000"">" & _
    Session("msg") & "</font></td></tr>" & _
    Session("msg") = ""
End If
sBody = sBody & "<tr><td align=""right""><b>Signon" & _
    "</b>:</td><td align=""left""><input " & _
    "type=""text"" name=""Signon""" & _
    "maxLength=""20""></td></tr>"
sBody = sBody & "<tr><td align=""right""><b>Password" & _
    "</b>:</td><td align=""left""><input " & _
    "type=""password""" & _
    "name=""Password"" maxLength=""20""></td></tr>"
sBody = sBody & "<tr><td align=""center""" & _
    "colspan=""2""><input type=""submit""" & _
    "value=""Register""></td></tr>"
s = Replace(s, "<!—Body—>", sBody)
Response.Write s
End Sub
  Note You cannot run the WebClass successfully until you add the getHTMLTemplate function. You'll see that within a few paragraphs.
Because we're not asking for much information in this application, there's little difference between the HTML for the Signon and the Registration screens. Normally, you would also ask for other information during registration, such as e_mail addresses, telephone numbers, street addresses, titles, etc. In any event, the important thing to notice here is that you can use WebClasses to manage the presentation layer or to generate it. Which one is best for you depends on your work situation and the needs of the program.
The Register_Respond event does contain some useful code. First, you'll eventually get tired of writing the standard HTML tags. That's why HTML editors invariably provide a template. The line s=getHTMLTemplate() shows you how easy this is to do in code. The getHTMLTemplate function returns an HTML string containing some replaceable markers for the title and body of the document. The markers are formatted as HTML comments, so (except for the title) they won't be visible in the browser if you don't replace them with valid HTML.
Private Function getHTMLTemplate() As String
    getHTMLTemplate = "<html><head><title>" & _
        "<!—Title—></title></head><body>" & _
        "<!—Body—></body></html>"
End Function
The rest of the Register_Respond routine sets up the HTML to display the screen. Finally, the routine uses the replace function to insert the title and body of the document in place of the markers.
In the Signon HTML Template, you hard-coded the URL for the form submission. In this routine, you let the WebClass dynamically create the URL by using the URLFor function. The URLFor function takes one or two parameters—a WebItem object (or a string containing the name of a WebItem) and, optionally, the name of a method for the WebItem. The function returns a URL referencing the specified WebItem or method.
The advantage of using URLFor is that you can change the URL based on factors unknown at design time. For example, suppose you have administrative users and non-administrative users, who have different privilege levels. If you use hard-coded URLs in HTML templates, you need to have more than one template. If you use dynamic URLs, you make a decision at runtime to display the appropriate URL based on the user's privilege level. If you want to see what the WebClass inserts into the HTML string, right-click the Registration page at runtime and select View Source from the pop-up menu.
When the user clicks the Submit button, you need to validate the registration information and store it in the registration file. You need to create another custom event. Right-click the Register WebItem in the WebClass Designer window and select Add Custom Event. Name the event Register so it will match the name in the URLFor function call.
Listing 5.3 contains the Register_Register event code.
Listing 5.3: SecuredSite Registration Event Code (in Signon.dsr)
Private Sub Register_Register()
    Dim i As Long
    Dim s As String
    Dim aSignon As String
    Dim aPassword As String
    Dim success As Boolean
    On Error GoTo Err_Register
    Session("msg") = ""
    aSignon = Request("Signon")
    ' check for valid values
    If Len(Trim(aSignon)) = 0 Then
        Session("msg") = "You must enter a sign-on."
        Set NextItem = Register
        Exit Sub
    End If
    aPassword = Request("Password")
    If Len(Trim(aPassword)) = 0 Then
        Session("msg") = "You must enter a password."
        Set NextItem = Register
        Exit Sub
    End If
    If InStr(aSignon, " ") > 0 Or _
InStr(aPassword, " ") > 0 Then
        Session("msg") = "You may not enter " & _
            "spaces in your signon or password."
        Set NextItem = Register
        Exit Sub
    End If
    If findSignon(aSignon) Then
        ' signon already used
        Session("msg") = "That sign-on is not " & _
            "available. Try again."
        Set NextItem = Register
    Else
        Call appendToTextFile(App.Path _
            & "\registration.txt", aSignon _
            & "," & aPassword)
        Set NextItem = Congratulations
    End If
Exit_Register:
    Exit Sub
Err_Register:
    Session("msg") = "Error: " & Err.Number & _
        "<BR>Source: " & Err.Source & "<BR>Description: " & _
        Err.Description
    Set NextItem = Register
    Resume Exit_Register
End Sub
  Note The code in the Register_Register event will not execute successfully until you add the code from the remainder of this section.
The first part of this routine only validates the information entered. After you're sure that you have valid information, the routine tries to find the sign-on. For this program, finding the sign-on is a two-part process. First, the findSignon function calls a function called readTextFile:
s = readTextFile(App.Path & "\registration.txt")
You'll see the code for the readTextFile function shortly, but I want to introduce two new objects first. The readTextFile function uses the Scripting.File-SystemObject to open and read the text file. It returns a string containing the textfile contents. The FileSystemObject is part of the Microsoft Scripting Runtime Library installed with both ASP and Visual Basic 6. It can check for the existence of files and can copy or move files. The FileSystemObject by itself cannot read files, but it provides an OpenTextFile method, which returns a TextStream object that can read and write text files. The VB documentation explains how to use the FileSystemObject and the TextStream object in detail, but basically, you provide a filename, a constant describing the action you want to take (ForReading, ForWriting, or ForAppending), and optionally, a Format constant that sets the Text-Stream object to use either ASCII or Unicode. The Format constants are Tri- StateTrue, TriStateFalse, TriStateMixed, and TriStateUseDefault. Of course, you don't have to use the FileSystemObject—you could use standard VB file access methods instead.
Add the readTextFile function to the Signon WebClass.
Private Function readTextFile(aFilename As String) As String
    Dim fs As FileSystemObject
    Dim ts As TextStream
    Dim s As String
    On Error GoTo Err_readTextFile
    Set fs = New FileSystemObject
    Set ts = fs.OpenTextFile(aFilename, ForReading, _
True, TristateUseDefault)
    If Not ts.AtEndOfStream Then
        s = ts.ReadAll
    End If
    ts.Close
    Set ts = Nothing
    Set fs = Nothing
    readTextFile = s
Exit_readTextFile:
    Exit Function
Err_readTextFile:
    Err.Raise Err.Number, "readTextFile", Err.Description
    Resume Exit_readTextFile
End Function
Remember, we decided to store the sign-ons and passwords as comma-delimited items, one per line. The findSignon routine splits the string returned from the readTextFile function into an array, then iterates through the array, splitting each line item into a two-item array at the comma.
Add the findSignon function to the Signon WebClass.
Private Function findSignon(aSignon, Optional retInfo _
As Variant) As Boolean
    Dim vArr As Variant
    Dim lRegCount As Long
    Dim i As Integer
    Dim arrSignonInfo As Variant
    Dim s As String
    On Error GoTo Err_FindSignon
    s = readTextFile(App.Path & "\registration.txt")
    If Len(s) > 0 Then
        s = Left$(s, Len(s) - 2)
        vArr = Split(s, vbCrLf)
        lRegCount = UBound(vArr)
        For i = 0 To lRegCount
            arrSignonInfo = Split(vArr(i), ",")
            If StrComp(aSignon, arrSignonInfo(0), _
                vbTextCompare) = 0 Then
                findSignon = True
                If Not IsMissing(retInfo) Then
                    retInfo = vArr(i)
                End If
                Exit Function
            End If
        Next
    End If
Exit_FindSignon:
    Exit Function
Err_FindSignon:
    Err.Raise Err.Number, Err.Source, Err.Description
    Resume Exit_FindSignon
End Function
If the routine finds a matching sign-on, it returns True. If you include the optional retInfo parameter, the findSignon routine sets it to the matching item.
The Register_Register routine checks the return value from findSignon to see whether any other user has already selected the requested sign-on. If so, it asks the user to select a different sign-on; if not, it appends the sign-on and password to the registration file and displays a Congratulations message containing a link back to the Signon screen. After registration, the user should be able to sign on successfully.
The Register_Register routine calls an appendToTextFile method to append the new sign-on and password. Again, the code uses the Scripting.FileSystem-Object and TextStream objects to write to the registration.txt file. Add the code for the appendToTextFile method to the Signon WebClass.
Private Sub appendToTextFile(aFilename As String, _
    value As Variant)
    Dim fs As FileSystemObject
    Dim ts As TextStream
    Dim v As Variant
    Dim i As Long
    Dim itemCount As Long
    On Error GoTo Err_appendToTextFile
    ' open the text file in Append mode
    Set fs = New FileSystemObject
    Set ts = fs.OpenTextFile(aFilename, ForAppending, _
        True, TristateUseDefault)
    If (VarType(value) And vbArray) = vbArray Then
        itemCount = UBound(value)
        For Each v In value
            ts.WriteLine v
        Next
    Else
        ts.WriteLine value
    End If
    ts.Close
    Set ts = Nothing
    Set fs = Nothing
Exit_appendToTextFile:
    Exit Sub
Err_appendToTextFile:
    App.LogEvent "Unable to append to the file: " & _
    aFilename & " in the appendtoTextFile routine."
    Err.Raise Err.Number, "appendToTextFile", _
        Err.Description
    Resume Exit_appendToTextFile
End Sub
You need to add another Custom WebItem to display the Congratulations message. Right-click the Custom WebItems entry in the WebClass Designer and select Add Custom WebItem. Rename the new WebItem Congratulations. Double-click the Congratulations WebItem and replace the empty Congratulations_ Respond event code with the following code:
Private Sub Congratulations_Respond()
    Dim s As String
    Dim sBody As String
    s = getHTMLTemplate()
    s = Replace(s, "<!—Title—>", "Congratulations")
    sBody = "You have successfully registered. Click <a href=""" _
    & URLFor(Signon) & """ target=""_top"">here</a> to continue."
    s = Replace(s, "<!—Body—>", sBody)
    Response.Write s
End Sub
You're almost done. You have all the routines needed for the sign-on; now you just need to call them from the Signon_frmSignon method. Here's the completed code for the Signon_frmSignon method:
Private Sub Signon_frmSignon()
    Dim aSignon As String
    Dim aPassword As String
    Dim action As String
    Dim tmpSignon As String
    Dim tmpPassword As String
    Dim arrSignonInfo As Variant
    Dim v As Variant
    action = Request.Form("Submit")
    If action = "Register" Then
        Set NextItem = Register
        Exit Sub
    End If
    Session("LastSignon") = ""
    Session("LastPassword") = ""
    aSignon = Request.Form("Signon")
    aPassword = Request.Form("Password")
    If Trim(aSignon) = vbNullString Then
        Session("msg") = "You must enter a signon."
        Set NextItem = Signon
        Exit Sub
    End If
    Session("LastSignon") = aSignon
    If aPassword = vbNullString Then
        Session("msg") = "You must enter a password."
        Set NextItem = Signon
        Exit Sub
    End If
    Session("LastPassword") = aPassword
    If findSignon(aSignon, arrSignonInfo) Then
        arrSignonInfo = Split(arrSignonInfo, ",")
        If StrComp(aPassword, arrSignonInfo(1), _
            vbTextCompare) = 0 Then
            Session("Signon") = aSignon
            Session("Password") = aPassword
            With Response
                .Write "Finished checking password" _
                     & "/signon." & "<BR>"
                .Write "Signon=" & aSignon & "<BR>"
                .Write "Password=" & aPassword & "<BR>"
            End With
        Else
            Session("msg") = "Invalid Password"
            Set NextItem = Signon
        End If
    Else
        Session("msg") = "Unrecognized Signon. " _
        & "Try again or click the Register button " _
        & "to register."
        Set NextItem = Signon
    End If
End Sub
You should now be able to run the project. When you register successfully, you should see the Congratulations message in your browser. In the next section, you'll see how to use the sign-on and password WebClass to force users to sign on before viewing any content pages in your application.



Visual Basic Developer[ap]s Guide to ASP and IIS
Visual Basic Developer[ap]s Guide to ASP and IIS
ISBN: 782125573
EAN: N/A
Year: 2005
Pages: 98

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net