【问题标题】:Get Connection's IP Address in SQL Server without VIEW SERVER STATE permission?在没有 VIEW SERVER STATE 权限的情况下在 SQL Server 中获取连接的 IP 地址?
【发布时间】:2013-10-05 21:29:20
【问题描述】:

有没有办法在用户不处于系统管理员角色或被授予查看服务器状态的情况下获取连接的 IP 地址?发出此查询需要其中之一:

select client_net_address from sys.dm_exec_connections where session_id = @@spid

我想在一个 Instead-Of 触发器中记录 IP 地址,但我不想将 VIEW SERVER STATE 权限授予所有用户。

感谢您的任何建议。


跟进 2013-10-05: 感谢各种cmets。将 VIEW SERVER STATE 授予所有用户有什么危险?

【问题讨论】:

    标签: sql-server ip-address


    【解决方案1】:

    您可以设置触发器以所有者身份执行:

    ALTER TRIGGER dbo.whatever_instead
    ON dbo.whatever
    WITH EXECUTE AS OWNER
    INSTEAD OF INSERT
    AS
    BEGIN
      SET NOCOUNT ON;
    
      INSERT dbo.log_table(column1, ...)
      SELECT client_net_address, ...
        FROM sys.dm_exec_connections 
        WHERE session_id = @@SPID;
    
      ... other stuff here I'm sure ...
    END
    GO
    

    但是,默认情况下,您应该收到以下错误:

    Msg 15562,级别 16,状态 1,过程whatever_instead
    正在执行的模块不受信任。要么需要授予模块数据库的所有者身份验证权限,要么需要对模块进行数字签名。 声明已终止。

    解决此问题的一种方法是将您的数据库设置为TRUSTWORTHY

    ALTER DATABASE database_name SET TRUSTWORTHY ON;
    

    不要掉以轻心:

    【讨论】:

    • 谢谢。看来我需要 TRUSTWORTHY ON 才能使用 CLR UDF。
    【解决方案2】:
    CREATE PROCEDURE Some_Proc
    WITH EXECUTE AS 'User_With_Permission'
    AS
    BEGIN 
        SET NOCOUNT ON;
            select client_net_address from sys.dm_exec_connections where session_id = @@spid
    END
    

    从你的触发器调用这个过程

    【讨论】:

    • 这仍然会产生错误 15562,除非模块已签名或数据库设置为可信任。因此,将其封装在存储过程中是一个额外且不必要的步骤。
    • 即使我们将 GRANT IMPERSONATE ON LOGIN::[login_to_be_impersonated] 授予 [login1];
    • 你试过了吗?你能包含一些代码来证明它是有效的吗?
    • Opss 我自己刚刚尝试过,但没有成功,很抱歉尝试与您争论:D 刚刚看到您的个人资料。好吧,我想至少我在发布这篇文章后学到了一些东西。谢谢亚伦:)
    • 像蝴蝶一样漂浮,像蜜蜂一样刺痛
    猜你喜欢
    • 2021-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多