ASP.NET - Log User Session Start/End Times for Aud

2019-07-30 09:49发布

问题:

My ASP.NET intranet web application uses Windows Authentication, and I would like to record the following details:

1) Windows ID
2) Session Start Time
3) Session Stop Time
4) URL being browsed to (optional)

I've got some basic code setup in "Session_Start" method of the Global.ASAX to log session start times (seen below), but that's it so far. I have the feeling this is a primitive approach and there are "better" ways of doing this. So I really have two questions:

1) Is this the right way to go about doing this? If not what are some other options?

2) If this is the right way, do I just need to drop some code in the "Session_End" method to record the time they exit, and thats a complete solution? Does this method always get called when they close the browser tab they have the site open in, or do they have to close the entire browser (I don't have logout functionality)? Any way users can skip over this session end method (or start for that case)?

    Dim connsql As New System.Data.SqlClient.SqlConnection(ConfigurationManager.ConnectionStrings("MyConnectionstring").ConnectionString)
    Dim cmdsql As System.Data.SqlClient.SqlCommand = connsql.CreateCommand
    cmdsql.CommandText = "BeginUserSession"
    cmdsql.CommandType = Data.CommandType.StoredProcedure
    Try
        cmdsql.Parameters.Add("@windowsid", System.Data.SqlDbType.VarChar, 30, "windowsid")
        cmdsql.Parameters("@windowsid").Value = Session("UserInfo").identity.name
        If connsql.State <> System.Data.ConnectionState.Open Then connsql.Open()
        cmdsql.ExecuteNonQuery()
        connsql.Close()

    Catch ex As Exception

    Finally
        If connsql.State <> Data.ConnectionState.Closed Then connsql.Close()
    End Try
    'Stored Proc records start time

回答1:

Session_End is not reliable.

What I would suggest is on Session_Start you create a record that notes the time the Session was created, and in Session_End you update the record with the time it was ended.

To handle the majority of sessions which are passively abandoned, use Application_BeginRequest to update the record to note when the user was "last seen".

You will then need to determine a way of marking sessions that have been passively abandoned. This will be site/app specific. It could be as simple as picking a number of minutes that must pass before the session is considered abandoned - like 10 minutes.

So then you have a query:

SELECT Username,
       SessionStart,
       SessionEnd,
       LastSeenOn,
       DATEDIFF(mi, SessionStart, ISNULL(SessionEnd, LastSeenOn)) DurationMinutes
FROM   SessionAudit
WHERE  SessionEnd IS NOT NULL
OR     DATEDIFF(mi, LastSeenOn, getdate()) > 10

Which will bring back your session audit log.



回答2:

Your approach could be described as simple, but that could be totally fine - it comes down to what the requirements are. If you need to log a full suite of application errors and warnings, look at implementing something like Log4Net. Otherwise I wouldn't say there is anything wrong with what you are doing.

Sessions are ended when there has been no user activity for the amount of time specified in the timeout value, or when you explicitly call Session.Abandon() in your code. Because of the stateless nature of HTTP, there is no way to tell if a user has left your site, closed the browser or otherwise stopped being interactive with their session.



回答3:

I am not sure you can catch the end of the session accurately because

  1. The user can close their browser and that will not necessarily end the session.
  2. They can then go back to your site and thus may have multiple sessions.

You can try messing with setting in IIS to kill the session very quickly after inactivity but its not a good idea.

Also... If the users are not all on an internal network you will have no control as to whether they have a "Windows ID" or not.