sqlserver 登录记录(登录触发器)
Posted 鱼日文弓虽
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了sqlserver 登录记录(登录触发器)相关的知识,希望对你有一定的参考价值。
本人自用 sqlserver 账号登录的记录(记录表+登录触发器)
--存储账号的登录记录信息 use [YWmonitor] go create table access_log ( [code] [int] IDENTITY(1,1) NOT NULL, [session_id] [int] NULL, [login_time] datetime NULL, [host_name] [varchar](50) NULL, [original_login_name] [varchar](50) NULL, [client_net_address] [varchar](50) NULL, CONSTRAINT [PK_access_log] PRIMARY KEY CLUSTERED ( [code] ASC )WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY] ) ON [PRIMARY]
--登录触发器设置(确保sa用户可用) use master go CREATE TRIGGER [tr_connection_limit] ON ALL SERVER WITH EXECUTE AS \'sa\' FOR LOGON AS BEGIN INSERT INTO [YWmonitor].[dbo].[access_log] ([session_id],[login_time],[host_name],[original_login_name],[client_net_address]) SELECT a.[session_id],a.[login_time],a.[host_name], a.[original_login_name],b.[client_net_address] FROM MASTER.sys.dm_exec_sessions a INNER JOIN MASTER.sys.dm_exec_connections b ON a.session_id=b.session_id END
登陆触发器能为我们解决什么问题呢?本文将为你讲述5种运用登陆触发器的场景:
1) 限制某登录名(比如sa)只能在本机或者指定的IP中登陆;
2) 限制服务器角色(比如sysadmin)只能在本机或者指定的IP中登陆;
3) 限制某登录名(比如sa)只能某时间段内登陆;
4) 限制登录名与IP的对应关系,支持多对多关系;
5) 限制某登录名可以在某IP段登录
下面是借用 ’听风吹雨‘ 的几个常用的触发器设置:
CREATE LOGIN test WITH PASSWORD = \'123\' GO -- ============================================= -- Author: <听风吹雨> -- Create date: <2013.05.21> -- Description: <限制test用户只能在本机和指定的IP中登陆> -- Blog: <http://www.cnblogs.com/gaizai/> -- ============================================= CREATE TRIGGER [tr_connection_limit] ON ALL SERVER WITH EXECUTE AS \'sa\' FOR LOGON AS BEGIN --限制test这个帐号的连接 IF ORIGINAL_LOGIN()= \'test\' --允许test在本机和下面的IP登录 AND (SELECT EVENTDATA().value(\'(/EVENT_INSTANCE/ClientHost)[1]\', \'NVARCHAR(15)\')) NOT IN(\'<local machine>\',\'192.168.1.50\',\'192.168.1.120\') ROLLBACK; END;
--插入测试数据 INSERT [dbo].[ValidLogOn] ([LoginName], [ValidIP]) VALUES (N\'nightworker\', N\'192.168.1.*\') --创建登录触发器 -- ============================================= -- Author: <听风吹雨> -- Create date: <2013.05.21> -- Description: <登陆名和IP过滤,支持IP范围规范> -- Blog: <http://www.cnblogs.com/gaizai/> -- ============================================= CREATE TRIGGER [tr_logon_CheckLogOn_RangeIP] ON ALL SERVER WITH EXECUTE AS \'sa\' FOR LOGON AS BEGIN DECLARE @LoginName sysname DECLARE @IP NVARCHAR(15) DECLARE @ValidIP NVARCHAR(15) DECLARE @len INT DECLARE @data XML DECLARE @blocked BIT; SET @len = 0 SET @blocked = 0 SET @LoginName = ORIGINAL_LOGIN(); SET @data = EVENTDATA(); SET @IP = @data.value(\'(/EVENT_INSTANCE/ClientHost)[1]\', \'NVARCHAR(15)\'); --判断登录名和IP IF NOT EXISTS(SELECT [ValidIP] FROM [Logon_DB].[dbo].[ValidLogOn] WHERE [LoginName] = @LoginName AND [ValidIP] = @IP) BEGIN --是否存在IP范围匹配 SET @ValidIP = (SELECT TOP 1 [ValidIP] FROM [Logon_DB].[dbo].[ValidLogOn] WHERE [LoginName] = @LoginName AND [ValidIP] LIKE \'%[*]\'); --如果存在就替换Client的IP IF (CHARINDEX(\'*\',@ValidIP) > 0 AND @IP <> \'<local machine>\' AND @IP <> \'127.0.0.1\') BEGIN DECLARE @SubValidIP NVARCHAR(15) SET @SubValidIP = SUBSTRING(@ValidIP,0,CHARINDEX(\'*\',@ValidIP)) SET @len = LEN(@SubValidIP) + 1 IF(SUBSTRING(@IP,0,@len) != @SubValidIP) BEGIN ROLLBACK; SET @blocked = 1 END END ELSE BEGIN ROLLBACK; SET @blocked = 1 END END --日志记录 INSERT INTO [Logon_DB].[dbo].[LogonLog] ([session_id] ,[login_time] ,[host_name] ,[original_login_name] ,[client_net_address] ,[XmlEvent] ,[Blocked]) SELECT @data.value(\'(/EVENT_INSTANCE/SPID)[1]\', \'smallint\'), GETDATE(), @data.value(\'(/EVENT_INSTANCE/ServerName)[1]\', \'sysname\'), @data.value(\'(/EVENT_INSTANCE/LoginName)[1]\', \'sysname\'), @data.value(\'(/EVENT_INSTANCE/ClientHost)[1]\', \'NVARCHAR(15)\'), @data,@blocked END;
数据库操作记录触发器设计举例:
--创建表:VERSION_CONTROL_TABLE CREATE TABLE [dbo].[VERSION_CONTROL_TABLE]( [ID] [bigint] IDENTITY(1,1) NOT NULL, [databasename] [varchar](256) NULL, [eventtype] [varchar](50) NULL, [objectname] [varchar](256) NULL, [objecttype] [varchar](25) NULL, [sqlcommand] [nvarchar](max) NULL, [loginname] [varchar](256) NULL, [hostname] [varchar](256) NULL, [PostTime] [datetime] NULL, [Version] [int] NOT NULL, CONSTRAINT [PK_VERSION_CONTROL_TABLE] PRIMARY KEY CLUSTERED ( [ID] ASC )WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY] ) ON [PRIMARY] ---创建触发器:TRG_VERSION_CONTROL_TABLE CREATE TRIGGER [TRG_VERSION_CONTROL_TABLE] ON DATABASE FOR CREATE_PROCEDURE, ALTER_PROCEDURE, DROP_PROCEDURE, CREATE_TABLE, ALTER_TABLE, DROP_TABLE, CREATE_FUNCTION, ALTER_FUNCTION, DROP_FUNCTION, CREATE_TRIGGER, ALTER_TRIGGER, DROP_TRIGGER, CREATE_VIEW, ALTER_VIEW, DROP_VIEW, CREATE_INDEX, ALTER_INDEX, DROP_INDEX AS SET NOCOUNT ON DECLARE @CurrentVersion int DECLARE @CurrentID int DECLARE @DatabaseName varchar(256) DECLARE @ObjectName varchar(256) DECLARE @data XML SET @data = EVENTDATA() INSERT INTO dbo.VERSION_CONTROL_TABLE(databasename, eventtype,objectname, objecttype, sqlcommand, loginname,Hostname,PostTime, Version) VALUES( @data.value(\'(/EVENT_INSTANCE/DatabaseName)[1]\', \'varchar(256)\'), @data.value(\'(/EVENT_INSTANCE/EventType)[1]\', \'varchar(50)\'), -- value is case-sensitive @data.value(\'(/EVENT_INSTANCE/ObjectName)[1]\', \'varchar(256)\'), @data.value(\'(/EVENT_INSTANCE/ObjectType)[1]\', \'varchar(25)\'), @data.value(\'(/EVENT_INSTANCE/TSQLCommand)[1]\', \'varchar(max)\'), @data.value(\'(/EVENT_INSTANCE/LoginName)[1]\', \'varchar(256)\'), HOST_NAME(), GETDATE(), 0 ) SET @CurrentID = IDENT_CURRENT(\'VERSION_CONTROL_TABLE\') SELECT @DatabaseName = databasename, @ObjectName = objectname FROM VERSION_CONTROL_TABLE WHERE ID = @CurrentID IF (@DatabaseName IS NOT NULL AND @ObjectName IS NOT NULL) BEGIN SELECT @CurrentVersion = MAX(Version) FROM VERSION_CONTROL_TABLE WHERE databasename = @DatabaseName AND objectname = @ObjectName UPDATE VERSION_CONTROL_TABLE SET Version = ISNULL(@CurrentVersion, 0) + 1 WHERE ID = @CurrentID END
以上是关于sqlserver 登录记录(登录触发器)的主要内容,如果未能解决你的问题,请参考以下文章