• 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
  • 相关阅读:
    React 生命周期
    css 多行文本以...代替
    微信JSSDK配置文件说明
    zepto阻止事件冒泡
    PHP 图片处理PNG颜色丢失
    React 学习笔记(一)
    webpack webpack-dev-server使用指南
    为什么需要使用模块打包工具?
    如何实现微信公户绑定公众号业务
    iOS 手势
  • 原文地址:https://www.cnblogs.com/lx823706/p/7146986.html
Copyright © 2020-2023  润新知