When you think ASP, think...
Recent Articles
All Articles
ASP.NET Articles
ASPFAQs.com
Message Board
Related Web Technologies
User Tips!
Coding Tips

Sections:
Sample Chapters
Commonly Asked Message Board Questions
JavaScript Tutorials
MSDN Communities Hub
Official Docs
Security
Stump the SQL Guru!
XML Info
Information:
Feedback
Author an Article
ASP ASP.NET ASP FAQs Message Board Feedback
Print this page.
Published: Wednesday, September 06, 2000

Logins and Permissions, Part 4

By Peter McMahon


  • Read Part 1
  • Read Part 2
  • Read Part 3

  • In Part 3 we looked at securing each Web page so that only those individuals who had properly logged in through our login screen could reach sensitive Web pages. In this part we'll look at more advanced security techniques!

    - continued -

    More Advanced Logins and Security Techniques
    If you have a small site, with a small number of user groups and users, then the solution above should be enough for your site. If however this method is becoming tedious to control and the limitations have been reached, then you need to go to the next step. The major difference between this login and the last one is that not only does this login have a Status variable, but also an ID variable. This is best explained with an example.

    ABC Inc is a sales company with regular clients. All their sales are managed through a web-based interface. All the sales are in a table called Sales. Each salesperson for the company has their own login, but may only edit or delete the sales that they themselves have made. Using our first login method, we would have to make a new user group for each user, and have a different edit/delete sales page for every single salesman. When you have more than five or so salespersons, this becomes a problem. The solution is to then keep the status, so that you can immediately kick out any unauthorized person who has not even logged in as a salesperson, but also store all the salespersons in a table, each with their own ID. Both the logins table and the sales table would have these ID numbers for each entry. For example, in the Salesperson table, you have the following data:

    Salesperson Table
    Salesperson NameID
    John Baker1152
    James Sefton1153

    The Logins table would then include:

    Logins Table
    Login NamePasswordStatusID
    John BakerSomepassSalesperson1152
    James SeftonAnotherpassSalesperson1153

    The Sales table would then look something like this:

    Sales Table
    DateCustomer IDSalesperson IDDetails
    05/06/20003481152Stationery
    04/06/20003671152Packaging Materials
    04/06/20001321153Stationery

    As you can see, the ID of the salesperson is common throughout. When the user now logs in, it no longer only sets the Status session variable, but also an ID session variable, drawn from the ID field in the logins table. The updated code would look like this:

    <%
       Response.Buffer = True
       Dim objConn, objRS
       Session.Contents("status") = ""
       Set objConn = Server.CreateObject("ADODB.Connection")
       objConn.Open "DSN=LoginTest;"
       Set objRS = objConn.Execute("SELECT * FROM Logins WHERE Username = '" & _
          Request.Form("txtUsername") & "'")
       If Not objRS.EOF Then
          If objRS(1) = Request.Form("txtPassword") Then
             Session.Contents("status") = objRS(2) ‘status column
             Session.Contents("id") = objRS(3) ‘ID column
             Response.Redirect "menu.asp"
          Else
             Response.Write “Sorry, but the password that you entered is incorrect.”
          End If
       Else
          Response.Write "Sorry, but the username does not exist."
       End If
       objRS.Close
       Set objRS = Nothing
       objConn.Close
       Set objConn = Nothing
    %>
    

    The only difference is the inclusion of the line, Session.Contents("id") = objRS(3). The major changes to the code occur in each of the secured pages. The code at the top of the page does not change at all and remains as:

    <%
       Response.Buffer = True
       If Session.Contents("status") <> "Salesperson" AND _
          Session.Contents("status") <> "Administrator" Then
          Response.Redirect "login.html"
       End If
    %>
    

    The change occurs where entries are drawn from the sales table. Let's give the salesperson the option to search the sales table in their menu. We'll let them search by date, so our search form would look like this:

    <%
       Response.Buffer = True
       If Session.Contents("status") <> "Salesperson" AND _
          Session.Contents("status") <> "Administrator" Then
          Response.Redirect "login.html"
       End If
    %>
    <HTML>
    <HEAD>
    <TITLE>ABC Inc. Sales Search</TITLE>
    </HEAD>
    <BODY>
    <TABLE BORDER="0">
    <FORM ACTION="search_results.asp" METHOD="post">
    <TR>
       <TD VALIGN="Top">Date:</TD>
       <TD VALIGN="Top"><INPUT TYPE="text" NAME="txtDate"></TD>
    </TR>
    <TR>
       <TD></TD>
       <TD><INPUT TYPE="submit" VALUE="Search"></TD>
    </TR>
    </FORM>
    </TABLE>
    </BODY>
    </HTML>
    

    This file would obviously have to be an ASP file to process the security instructions at the top of the page. Since all the salespersons will be allowed to see everything on the page, there is no need to perform ID specific checks. The next page, search_results.asp, will however require making use of the ID as only the sales that belong to the salesperson that is currently logged in must be displayed when the search is performed. This is done using two conditions in the WHERE SQL statement. The first condition is the date, which is loaded from the form post variable and the second is the SalespersonID field, which is loaded from the session variable. The salesperson does not know that this filtering has automatically been done for him. Not only is this an advantage in the terms of privacy and security amongst the agents, but it is also a convenience, as the salesperson does then not have to wade through hundreds of sales that are not even remotely related to him. Here's the code used:

    <%
       Response.Buffer = True
       If Session.Contents("status") <> "Salesperson" AND _
          Session.Contents("status") <> "Administrator" Then
          Response.Redirect "login.html"
       End If
    %>
    <HTML>
    <HEAD>
    <TITLE>ABC Inc. Sales Search Results</TITLE>
    </HEAD>
    <BODY>
    <B>Search Results for <%=Request.Form("txtDate")%></B><BR><BR>
    <TABLE BORDER="0">
    <TR>
       <TD VALIGN="Top"><B>Date</B></TD>
       <TD VALIGN="Top"><B>Customer ID</B></TD>
       <TD VALIGN="Top"><B>Details</B></TD>
    </TR>
    <%
       Dim objConn, objRS
       Set objConn = Server.CreateObject("ADODB.Connection")
       objConn.Open "DSN=LoginTest;"
       Set objRS = objConn.Execut("SELECT * FROM Sales WHERE Date = #" & _
          Request.Form("txtDate") & "# AND SalesPersonID = " & _
          Session.Contents("id"))
       While Not objRS.EOF
    %>
    <TR>
       <TD VALIGN="Top"><%=objRS(0)%></TD>
       <TD VALIGN="Top"><%=objRS(1)%></TD>
       <TD VALIGN="Top"><%=objRS(3)%></TD>
    </TR>
    
    <%
          objRS.MoveNext
       Wend
       objRS.Close
       Set objRS = Nothing
       objConn.Close
       Set objConn = Nothing
    %>
    </TABLE>
    </BODY>
    </HTML>
    

    The script is very basic, but it demonstrates how this ID information can be used. Other applications for this information can be for automatically adding the SalesPersonID field when a record is added to the Sales table. It can also be useful for site customization, where the user's homepage includes links to their favorite sites according to their login ID (a.k.a. who they logged in as.) This could be implemented using a "Favorite Links" table with a user ID column.

    That wraps up our talk on advanced security issues. In Part 5 we'll wrap up this article after discussing some possible enhancements to the system!

  • Read Part 5


  • ASP.NET [1.x] [2.0] | ASPMessageboard.com | ASPFAQs.com | Advertise | Feedback | Author an Article