- Equipment Deployment
- Authenticating Users
- Guarding Data
- Tracking User Activity
- Summary
Tracking User Activity
Many applications require that you give users access to sensitive resources. When the users are using those resources, you will want to be able to see what was done. What did they look at? What actions did they fire? What data did they change? Most of the time, the users will not abuse their privileges. However, when the users are new and when they are trying to do something wrong, you want to see what they did. It will help you back out the changes the newbie made. As a forensic tool, tracking the changes will help you identify who did what and when.
All of this involves creating some sort of an auditing strategy. In the best of all worlds, you will know exactly who is calling you. Auditing was discussed as a debugging tool in Chapter 5, "Troubleshooting Web Services/Consumers." For security, you can use auditing to determine what the user did and when he or she did it. What information do you track when auditing user activity? This set of data is specific to security:
User identity (if available)This lets you know who executed the action.
IP Address of callerThis allows you to track the call back to a specific machine. This comes in handy, even if the user is coming through some sort of proxy server.
Free text fieldYou will want some sort of generic field that allows you to put all audit data into one table. Within this field, you can enter information particular to the action the user was performing. Think of putting in information that would be helpful when capturing details about what happened.
Time of actionBy knowing when things happened, you will be able to figure out the order of the actions and string together what the user did.
Keep in mind that a lot of this information will be used only when something odd happens. Depending on what the Web Service allows users to do, you may want to write programs that analyze the audit data, looking for use patterns that look suspicious. So, what would this logging mechanism look like? Ideally, the auditing mechanism would use some sort of delayed write mechanism, such as inserting the item in to a queue and having a listener actually log the item to a database. I will highlight the one function you would want to adapt to actually use Microsoft Message Queue (MSMQ) instead of writing to a file, as is done in the example.
The code presents a class named Audit that handles extracting the audit data from the Web Service and storing the audit to a file. This class is used by a HelloWorld Web Method. The code, shown in Listing 6.7, is written using what I consider to be the recommended setup for making sure that the audit record always gets recorded for every Web Method that you audit.
Listing 6.7 Auditing HelloWorld and Making Sure That the Audit Data Is Always Written
<WebMethod()> Public Function HelloWorld() As String Dim theAudit As New Audit(Me, "Service1.HelloWorld", AuditLog) Try HelloWorld = "Hello World" theAudit.FreeText = "This is some free text." Catch ex As Exception theAudit.FreeText = ex.ToString() Finally theAudit.Store() End Try End Function
The Web Service should be set up to use HTTP Basic Authentication. This will allow us to easily track who is using the Web Service. The Audit class takes a reference to a WebService class, the name of the method being audited, and the name of the log file. In the constructor, shown in Listing 6.8, Audit captures everything but the free text and stores it to be written a little bit later.
Listing 6.8 Constructor for the Audit Class
Public Sub New( _ ByRef theContext As System.Web.Services.WebService, _ ByVal methodName As String, _ ByVal logFileName As String) ' Extract and store the important data. m_methodName = methodName m_logFileName = logFileName m_actionTime = DateTime.Now m_userID = theContext.User.Identity.Name m_callerIP = theContext.Context.Request.UserHostAddress End Sub
When the method being audited is ready to return, the code should store the log information. This gives the Web Method a chance to set the free text to anything that may happen while it is executing. Listing 6.9 shows how the data is then stored to the log file. This is the method you would want to update to write to an MSMQ because even file access can get to be time consuming as the file grows in size.
Listing 6.9 Storing the Audit Data to the Log
Public Sub Store() Dim fs As New System.IO.StreamWriter(m_logFileName, True) fs.Write(m_actionTime.ToString() & vbTab) fs.Write(m_methodName & vbTab) fs.Write(m_callerIP & vbTab) fs.Write(m_userID & vbTab) fs.WriteLine(m_freeText) fs.Close() End Sub
Table 6.1 shows the data that was stored in the log file when I logged in using two different accounts on my computer.
Table 6.1 Data Stored by Simple Audit Class
Time |
Method |
Client IP |
User ID |
Free Text |
12/4/2001 9:34:55 PM |
Service1.HelloWorld |
127.0.0.1 |
SCOTTNB\TestUser |
-This is some free text. |
12/4/2001 9:35:13 PM |
Service1.HelloWorld |
127.0.0.1 |
SCOTTNB\Dad |
-This is some free text. |
The method presented here depends on knowing the User ID. For a free Web Service, you could omit this data and still store the client IP address. Knowing this information will come in handy when particular addresses seem to be abusing your Web Service. Abuse includes looking for ways to bring your Web Service down, denial of service attempts, or anything else that you don't want to see happening on your server.