本人自用 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
时间: 2024-10-13 01:36:37