How would you audit ASP.NET Membership tables, whi

2019-07-16 08:17发布

问题:

Using a trigger-based approach to audit logging, I am recording the history of changes made to tables in the database. The approach I'm using (with a static sql server login) to record which user made the change involves running a stored procedure at the outset of each database connection. The triggers use this username when recording the audit rows. (The triggers are provided by the product OmniAudit.)

However, the ASP.NET Membership tables are accessed primarily through the Membership API. I need to pass in the current user's identity when the Membership API opens its database connection. I tried subclassing MembershipProvider but I cannot access the underlying database connection.

It seems like this would be a common problem. Does anyone know of any hooks we can access when the ASP.NET Membership makes its database connection?

回答1:

Update 2: Not looking good on the AOP front, I am afraid - see Is is possible to intercept a static method on an object you don't own and did not create?

And as alluded to in comments, it looks like the best bet is to use the Provider Toolkit's implementation of the providers and wire your hook into SqlConnectionHelper.GetConnection()

I use the toolkit code, which I have cleaned up considerably, reliably for years with no problems. Let me confirm on 4.0 and package it up if you are interested.


Update:

Ok, I think I better understand your need, tell me if I am correct:

You need the actual connection that is being used by the provider?

SqlMembershipProvider utilizes a helper class, System.Web.DataAccess.SqlConnectionHolder, for all of it's data access.

I have not done this, but from what I have gathered, you could intercept calls to build this object using an AOP implementation such as Castle DynamicProxy (or one of the libraries that leverage it) and get your connection there.

Could some one with more experience confirm or deny this?


Original answer:

No need to derive from SqlMembershipProvider. Just go in and get what you need.

string connectionString = 
   typeof(SqlMembershipProvider)
   .GetField("_sqlConnectionString",BindingFlags.NonPublic | BindingFlags.Instance)
   .GetValue(Membership.Provider);