How to implement context based DB auditing?
I have a current DB driven application which has several methods for accessing data.
- Web Application
- Direct SQL Access users (I'm trying to remove these)
- Client Server application
- Batch inputs and outputs
I need to implement context based au开发者_Go百科diting as the current data auditing is not enough for retrospective identification of what processes caused the data changes.
I am currently thinking of hiding the data model behind XAPIs (Transactional APIs) and each action on the data model will have to supply some form of identifying associated action or reason for the data change which will be stored alongside the audited data itself.
Can anyone offer me a better method for achieving context based auditing that will cover all access into the database? Or even point out any obvious flaws in my current approach that I have missed?
Thanks in advance.
This is an older post, but I still want to provide a solution, may be it will be useful for someone.
Oracle provides "context" variables for each session. In an application that uses connection pool to connect to the database, Oracle provides a default namespace called "CLIENTCONTEXT". With in that namespace you can create variables such as USER ID and make sure this variable is set when a connection is handed off to server web requests. This way, inside the database you can identify which "web user" (or app user per say) request is being handled inside the database. e.g. dbms_session.set_context('CLIENTCONTEXT',user_id, ); Hope it helps.
EDIT added context specific portion of answer to bottom
- Every user has a log-in.
- Tie those log-ins to SQL Server Users.
- Use the SYSTEM_USER (ex: select SYSTEM_USER) for your auditing.
The only place where the above becomes tricky is for the web app.
- I don't know if your web application is internal or not, (if it's internal, using windows authentication with impersonation/delegation would work great)
- If it's external you'll have a system defined account that will verify log ins into the web app (and possibly do other privileged operations), then you can use the user's own credentials for db access during the session.
- If you don't want to have a bunch of SQL Server Users you can do your own session management and create/drop the users on the fly (like when they log in / log out)
Here's some T-SQL to illustrate
-- AFTER SUCCESSFUL LOGIN
BEGIN
-- You would already have the user name and password
DECLARE @user varchar(32)
SET @user = 'tester'
DECLARE @pw varchar(32)
SET @pw = 'SuperTest123'
-- if the user logs in from 2 different sessions
-- keep the name more unique
SELECT @user = @user + REPLACE(NEWID(), '-', '')
-- build the dynamic sql to create a user
DECLARE @sql varchar(8000)
SELECT @sql = 'CREATE LOGIN [' + @user + '] WITH PASSWORD = ''' + @pw + '''; '
SELECT @sql = @sql + 'USE MyDatabase; CREATE USER [' + @user + '] FOR LOGIN [' + @user + '] WITH DEFAULT_SCHEMA = db_datareader; '
EXEC(@sql)
-- use these credentials for web apps sql connections
SELECT @user [UserName], @pw [Password]
END
-- AFTER LOGOUT / SESSION EXPIRATION
BEGIN
-- You would already have the user+guid used by the sql server
DECLARE @login varchar(32)
SET @login = 'tester3C8DA60B996C4E5881774D1FE4'
-- build the dynamic sql to drop user
DECLARE @sql varchar(8000)
SELECT @sql = 'DROP LOGIN [' + @login + ']; '
SELECT @sql = @sql + 'USE MyDatabase; DROP USER [' + @login + ']; '
EXEC(@sql)
-- user gone until next session
END
Context constraints can be achieved directly in the audit triggers.
- Table: TEMP_AUDITREASON
- [User] VARCHAR(128) DEFAULT SYSTEM_USER
- [Reason] VARCHAR(512)
- Trigger
This may be a little glib but...
IF EXIST(SELECT [Reason] FROM [TEMP_AUDITREASON] WHERE [User] = SYSTEM_USER AND [Reason] IS NOT NULL)
BEGIN
SELECT @REASON = [Reason] FROM [TEMP_AUDITREASON] WHERE [User] = SYSTEM_USER
-- clear it for the next transaction
DELETE FROM [TEMP_AUDITREASON] WHERE [User] = SYSTEM_USER
END
ELSE
BEGIN
-- SOUND THE ALARM!!! no reason was given
END
we had a project where we were required to have detailed audit information on what was changed, when and by whom.
in our case, what we did, is improved our MVC solution, to keep audit trail when things were changed. in that situation, we were able to store auxiliary information, such as web user, ip, etc.
additionally we had mysql binary logging enabled, thus we could roll back full history if necessary and given the additional logs stored about accesses to distinguish the source of change.
in your case it would be somewhat trickier, if you don't have any layer between database and actual database accesses. so, I would suggest creating api for operations with data which would work as intermediary layer and would give you all the control you are looking for.
this should give you directions to get started with.
精彩评论