views:

96

answers:

1

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  A: 

Update 2: Not looking good on the AOP front, I am afraid - see http://stackoverflow.com/questions/2912300/is-is-possible-to-intercept-a-constructor-on-a-class-you-do-not-own

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);
Sky Sanders
Thanks, very interesting idea. I was thinking that an AOP approach makes sense. Not sure I want to introduce another dependency on something like Castle right now though. Right now I am considering using the source for SqlMembershipProvider, which I just discovered is available. One concern I have is that this source code is from 2006, and I don't know if it's been updated with subsequent asp.net versions.
Pete
Actually, I have another question going regarding AOP and it does not look good for us..http://stackoverflow.com/questions/2912300/is-is-possible-to-intercept-a-constructor-on-a-class-you-do-not-own, but - my next suggestion was to use a custom provider based on the toolkit samples. I have refined that code quite a bit over the years and it works like a charm. Nothing has been changed that affects the suitability of that code. If you can wait a few days I will make my work available.
Sky Sanders
@Pete - ping... sorry, didn't @you- see update.
Sky Sanders
@code poet. Thanks! It's good to know that the MS-provided code works OK for you. I did modify GetConnection and that is working. My only concern is if MS has added security features to this library over the years, I won't have them. So far, it works identically to the built-in provider.
Pete