Logging UserID of user performing action

Posts   
 
    
bertcord avatar
bertcord
User
Posts: 206
Joined: 01-Dec-2003
# Posted on: 19-Aug-2004 19:23:19   

Ok so I thinking of how I want to do my logging . I am going to implement it my business layer classes for Action Procedures, and I will use a subclassed adapter for entity updates. Once thing I want to log is the userID performing the action. The majority of my experience is with web applications. To get user Info I use HttpContext.Current.User.Identity.Name() But I don't want to tie the adapter to the HTTPContext object. What is a good way to log user actions form the BL layer? Any help would be appreciated.

Thanks Bert

wayne avatar
wayne
User
Posts: 611
Joined: 07-Apr-2004
# Posted on: 20-Aug-2004 09:31:39   

Hi Bertcord

We have a web app - the user logs in - we save a record in a table identifying the loged in session with the user - We also save other info like IP Address, browser used and OS.

Our BL Objects require the userid / operatorid in their constructors. So our PL (Web App) constructs the BL with the userID if your BL consist out of static methods i suggest passing the userid as a param. Our BL Objects are build around self servcing Entities and our BL controls them. - All logging of user actions is done by a save method that is inherited by all BL Objects.

bertcord avatar
bertcord
User
Posts: 206
Joined: 01-Dec-2003
# Posted on: 20-Aug-2004 15:14:32   

Thanks for your response Wayne. My BL consists of static methods so I will pass the userInformation as params. I think I will create a UserInfo Object and pass that that has userid, IP...and thsi will alos let me add to it later....

thanks again.

Bert

MarcoP avatar
MarcoP
User
Posts: 270
Joined: 29-Sep-2004
# Posted on: 29-Sep-2004 20:59:10   

If you extend the current .net security infrastructure (IPrincipal, IIdentity), you can add your own properties and methods to these classes and pull the object off of the current thread from any of your layers. This way, your public interface is not getting extended and it seems to be a little cleaner.

brettlj
User
Posts: 27
Joined: 08-Feb-2004
# Posted on: 30-Sep-2004 21:14:18   

MarcoP wrote:

If you extend the current .net security infrastructure (IPrincipal, IIdentity), you can add your own properties and methods to these classes and pull the object off of the current thread from any of your layers. This way, your public interface is not getting extended and it seems to be a little cleaner.

This is the method I'll be using on an app I'm about ready to develop. You should read this blog entry by Scott Hanselman so that you understand a small quirk in using System.Threading.Thread.CurrentPrincipal in an ASP.NET application.

http://www.hanselman.com/blog/PermaLink.aspx?guid=22c42b73-4004-40ce-8af9-47f1b9b434ed

Devildog74
User
Posts: 719
Joined: 04-Feb-2004
# Posted on: 08-Oct-2004 05:53:36   

brett, I am not sure what the blog is "really" saying. You could have issues with the IPrincipal object due to thread switching taking place behind the scenes in the ASP.NET Runtime?

Can you elaborate a bit?

brettlj
User
Posts: 27
Joined: 08-Feb-2004
# Posted on: 25-Oct-2004 18:39:03   

Devildog74 wrote:

brett, I am not sure what the blog is "really" saying. You could have issues with the IPrincipal object due to thread switching taking place behind the scenes in the ASP.NET Runtime?

Can you elaborate a bit?

I had to read it about 5 times and do some looking around with Reflector before I really figured it out!!

Here's how I understand it: After the Application.AuthenticateRequest event is fired, ASP.NET runs the SetPrincipalOnThread method, which basically achieves this: System.Threading.Thread.CurrentPrincipal = System.Web.HttpContext.Current.User

As this is happening right after the AuthenticateRequest event, any references to Thread.CurrentPrincipal hereafter in the application will return the custom principal object (Current.User).

However, when HttpContext.Current.User is set in a page, any code running later on (in the same request though) that accesses Thread.CurrentPrincipal will NOT be getting the custom principal contained in HttpContext.Current.User. This is because the Application.AuthenticateRequest event has not yet fired for the current request, and thus the ASP.NET runtime has not yet set System.Threading.Thread.CurrentPrincipal = System.Web.HttpContext.Current.User.

Before: Request 1 1. Anonymous comes in, AuthenticateRequest does not fire 2. User logs in 3. HttpContext.Current.User set to MyCustomPrincipal 4. Code somewhere in app refers to Thread.CurrentPrincipal (this is currently whatever ASP.NET set it to, NOT MyCustomerPrincipal)

Request 2 1. Request comes in, and since HttpContext.Current.User is set, AuthenticateRequest fires 2. Thread.CurrentPrincipal is set to HttpContext.Current.User 3. Code somewhere in app refers to Thread.CurrentPrincipal, which is now the same as HttpContext.Current.User

After: Request 1 1. Anonymous comes in, AuthenticateRequest does not fire 2. User logs in 3. HttpContext.Current.User set to MyCustomPrincipal 4. Thread.CurrentPrincipal is set to HttpContext.Current.User 5. Code somewhere in app refers to Thread.CurrentPrincipal (this is now a MyCustomerPrincipal instance)