Reputation: 38033
I'm working in Entity Framework 5. We're using Microsoft Active Directory for user authentication. We're using a proper n-tier architecture, so for the most part, the business layer is blissfully unaware of the UI.
Now we have a requirement to keep a full audit trail: every time any write operation happens on the database, we have to save it to our audit log, along with who made the change.
Catching the write should be relatively simple; I'll just override SaveChanges()
in my data context and use the ObjectStateManager
to find all the inserts, updates and deletes. The real issue will be detecting who the current user is, since authentication is done on the presentation layer, and the business layer DLL will be hosted on IIS, servicing any number of client processes.
Is there some way to detect the authentication credentials that were used by the client, inside the business layer? I definitely do not want to have to pass user ID to every interface in the API!
(FWIW, I'm also using EntityFramework.Extended, which supposedly has some native AuditLog capabilities, but the documentation is woefully inadequate. Anyone with any experience using this successfully? Could it help?)
Upvotes: 3
Views: 1907
Reputation: 124746
You could consider passing the end-user's identity out-of-band, rather than adding it to every method signature.
For example, if you're using WCF you could create a behavior that injects a custom SOAP header client-side, and processes the custom header server-side.
UPDATE
Comments to the question appear to imply that the DLL is directly accessed from the ASP.NET MVC application, not via a web service. I had assumed from your statement that:
the business layer DLL will be hosted on IIS, servicing any number of client processes
that it was a web service called from multiple ASP.NET MVC applications.
If it's just a DLL included in your ASP.NET MVC application, it's very simple.
HttpContext.Current.User
will contain the identity of the connected client.
Rather than using HttpContext in the business tier, you should ensure that Thread.CurrentPrincipal
is set to the same principal as HttpContext.Current.User
.
If you are using an ASP.NET RoleProvider
, this will be done for you automatically. If not, you may need to do it manually, e.g. in the AuthorizeRequest event handler in global.asax.
Then in the business tier you access the end-user identity as Thread.CurrentPrincipal.Identity.Name
.
Upvotes: 2
Reputation: 91885
Provided you've configured authentication appropriately (e.g. Forms or Windows authentication), then Thread.CurrentPrincipal
is guaranteed to refer to the user making the request.
Upvotes: 3