Prz*_*min 17 sql t-sql sql-server ip stored-procedures
是否有可能,如果是这样,如何获得用户的远程IP地址执行查询,类似于我们可以获得用户的名字:SUSER_SNAME()?
在赏金之前更新
我正在寻找一种解决方案,它允许获取普通凡人用户的IP地址,而不是数据库所有者.TheGameiswar或njc提出的想法不允许捕获仅被授予execute权限的用户的IP地址.但是,它们是解决问题的绝佳方法.在这里,我列出了这些想法的精髓:
请看我遵循的顺序:
create procedure MyStoredProcedure as
select client_net_address
from sys.dm_exec_connections
where session_id = @@SPID
Run Code Online (Sandbox Code Playgroud)
现在添加用户并授予权限:
CREATE LOGIN [user_mortal_jack] WITH PASSWORD=N'LongYouLive!!!';
GRANT EXECUTE ON MyStoredProcedure TO [user_mortal_jack];
Run Code Online (Sandbox Code Playgroud)
当我使用查询运行该过程时:
EXECUTE AS USER = 'user_mortal_jack'
exec MyStoredProcedure
REVERT
Run Code Online (Sandbox Code Playgroud)
我收到错误消息:
正在执行的模块不受信任.需要为模块的数据库所有者授予身份验证权限,或者需要对模块进行数字签名.
即使我授予了额外的许可,我也会收到此消息:
grant VIEW SERVER STATE to [user_mortal_jack];
Run Code Online (Sandbox Code Playgroud)
如果我将存储过程的开头更改为:
create procedure MyStoredProcedure
with execute as OWNER as
Run Code Online (Sandbox Code Playgroud)
我最终得到了不同类型的错误:
无法获取有关Windows NT组/用户'blahblah\admin_user'的信息,错误代码为0x534.
赏金后更新
赏金被授予Hadi,因为他们的答案中隐藏着这一行代码:
CONNECTIONPROPERTY('client_net_address')
Run Code Online (Sandbox Code Playgroud)
让我们捕获任何凡人用户的IP地址,既不给予用户任何额外的权利,也不设置数据库TRUSTWORTHY ON选项,甚至不创建过程WITH EXECUTE AS OWNER子句.
Had*_*adi 14
有两种方法可以获取当前的连接信息
从动态管理视图获取信息
SELECT
conn.session_ID as SPID,
conn.client_net_address as IPAddress,
sess.host_name as MachineName,
sess.program_name as ApplicationName,
login_name as LoginName
FROM sys.dm_exec_connections conn
inner join sys.dm_exec_sessions sess
on conn.session_ID=sess.session_ID
Run Code Online (Sandbox Code Playgroud)使用CONNECTIONPROPERTY函数(SQL Server 2008和更高版本):
select
CONNECTIONPROPERTY('net_transport') AS net_transport,
CONNECTIONPROPERTY('protocol_type') AS protocol_type,
CONNECTIONPROPERTY('auth_scheme') AS auth_scheme,
CONNECTIONPROPERTY('local_net_address') AS local_net_address,
CONNECTIONPROPERTY('local_tcp_port') AS local_tcp_port,
CONNECTIONPROPERTY('client_net_address') AS client_net_address
Run Code Online (Sandbox Code Playgroud)如果您要授予用户特定的IP地址
CREATE PROCEDURE MyStoredProcedure AS
BEGIN
DECLARE @IP_Address varchar(255);
SELECT @IP_Address = CAST(CONNECTIONPROPERTY('client_net_address') as varchar(200))
IF @IP_Address = 'XXX.XXX.XXX.XXX'
SELECT TOP 1 FROM tb
END
Run Code Online (Sandbox Code Playgroud)假设您有一个包含授权IP地址的表(即TBL_IP)
CREATE PROCEDURE MyStoredProcedure AS BEGIN DECLARE @IP_Address varchar(255);
SELECT @IP_Address = CAST(CONNECTIONPROPERTY('client_net_address') as varchar(200))
IF EXISTS (SELECT 1 FROM TBL_IP WHERE [IP] = @IP_Address )
SELECT TOP 1 FROM tb
Run Code Online (Sandbox Code Playgroud)
结束
如果要授予用户(数据库用户)执行存储过程的权限,则应使用此命令
在MyStoredProcedure TO用户上执行GRANT EXECUTE;
有许多详细的文章和答案谈论您正面临的问题,以及许多建议的解决方案,例如在TRUSTWORTHY模式下设置数据库(在使用它之前阅读下面的第一个链接)和信任身份验证器,以及其他方法.您可以在下面的链接中找到它们
注意:您可以检查@SteveFord答案是否使用了TRUSTWORTHY属性
如果您希望阻止除特定IP地址之外的连接,那么您应该遵循此答案
此外,还有许多脚本可用于获取客户端或服务器IP地址,可在以下问题中找到:
参考