Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net SQL Server通过集成登录提升了权限_.net_Sql Server_Security_Permissions_Impersonation - Fatal编程技术网

.net SQL Server通过集成登录提升了权限

.net SQL Server通过集成登录提升了权限,.net,sql-server,security,permissions,impersonation,.net,Sql Server,Security,Permissions,Impersonation,我有一个在IIS中运行的应用程序,它使用windows集成身份验证连接到SQL Server 2008 R2实例。此应用程序使用一组存储过程在数据库中执行简单的读/写操作。对于这种登录/用户组合,我可以很好地限制SQL server中的权限 但对于应用程序的一小部分,我需要“提升”/数据库中更强大的权限。。。例如,创建/删除事件通知,并可能创建队列和代理服务 所以基本上我有一个进程,代码在连接到SQL server的同一个用户帐户下运行,我需要两组不同的权限。。。一个连接具有非常有限的权限,一个

我有一个在IIS中运行的应用程序,它使用windows集成身份验证连接到SQL Server 2008 R2实例。此应用程序使用一组存储过程在数据库中执行简单的读/写操作。对于这种登录/用户组合,我可以很好地限制SQL server中的权限

但对于应用程序的一小部分,我需要“提升”/数据库中更强大的权限。。。例如,创建/删除事件通知,并可能创建队列和代理服务

所以基本上我有一个进程,代码在连接到SQL server的同一个用户帐户下运行,我需要两组不同的权限。。。一个连接具有非常有限的权限,一个连接具有更强大的权限

我想使用windows集成身份验证。。。使用两个用户/密码组合的sql身份验证不是一个选项

有没有推荐的方法来实现这一点

  • 在应用程序代码中,使用集成安全性从模拟上下文(不同的用户帐户/SQL登录)连接到SQL Server时,我不喜欢模拟,因为我必须管理第二个登录/密码
  • SQL server应用程序角色(我认为需要应用程序提供的密码)-我不太喜欢它,因为我需要存储密码
  • 具有两个用户的SQL身份验证-不是选项
  • 为“提升的东西”创建专用存储过程,并使用
    执行为
    (应该可以,但是,不确定是否可以在目标数据库中创建存储过程)
  • 复杂的想法:启动应用程序进程,连接到数据库,限制应用程序令牌,然后打开权限较低的连接(这样行吗?)
  • 对应用程序的“提升”部分使用COM+()、WCF服务或第二个进程(太复杂)

我想我缺少了一些简单而简洁的解决方案…

这个简单的解决方案是您正在放弃的解决方案之一,使用一个资源帐户


创建具有适当权限的sql server用户id,并在特殊DDL类型的语句期间仅从应用程序中使用该资源帐户,将是最简单、最可维护的解决方案。

使用代码签名。您的所有“提升”操作都是从已签名的存储过程中完成的,信任是从该过程的签名中派生出来的。这是相当有效和强大的,而且非常安全。例如,假设您需要一种方法来创建绑定到
http://schemas.microsoft.com/SQL/Notifications/PostEventNotification
合同。因此,您需要运行以下代码:

create queue myQueue;
create service myService on queue myQueue (
[http://schemas.microsoft.com/SQL/Notifications/PostEventNotification]);
此语句需要提升权限:创建队列、创建服务和EN合同上的引用。您可以将这些语句嵌入到过程中,对过程进行签名,使用用于对过程进行签名的证书创建用户,然后向证书派生用户授予必要的权限:

create procedure usp_createQueueAndService
with execute as caller
as
begin
    create queue myQueue;
    create service myService on queue myQueue (
    [http://schemas.microsoft.com/SQL/Notifications/PostEventNotification]);
end
go

create certificate [certificateToSign_usp_createQueueAndService]
 ENCRYPTION BY PASSWORD = 'Password#1234'
 with subject = 'Code signing for usp_createQueueAndService';
go

ADD SIGNATURE TO OBJECT::[usp_createQueueAndService]
BY CERTIFICATE [certificateToSign_usp_createQueueAndService]
WITH PASSWORD = 'Password#1234';
go

ALTER CERTIFICATE [certificateToSign_usp_createQueueAndService]
REMOVE PRIVATE KEY;
GO

create user [certificateDerivedUser_usp_createQueueAndService]
from certificate [certificateToSign_usp_createQueueAndService];
go

grant create queue to [certificateDerivedUser_usp_createQueueAndService];
grant create service to [certificateDerivedUser_usp_createQueueAndService];
grant references on 
    contract::[http://schemas.microsoft.com/SQL/Notifications/PostEventNotification] 
    to [certificateDerivedUser_usp_createQueueAndService];
go
这是100%防弹安全。所有授予过程执行权限的调用方现在都可以创建队列和服务,因为过程本身通过签名被授予必要的权限。没有人可以修改该过程,因为修改该过程会丢失签名,从而丢失特权。任何人都不能滥用证书对另一个过程进行签名,因为私钥被丢弃并永远丢失(验证现有签名不需要私钥)

此模型可以扩展到您需要的任何权限,包括服务器范围的权限(需要证书派生的登录,而不是用户登录,请参阅)


当然,您可以让usp_createQueueAndService接受队列和服务名称作为参数,我将这部分留给读者作为一个简单的练习。如果您想使用事件通知,这种练习对您来说应该是微不足道的;)

您提到您可能没有创建过程的权限:您在应用程序部署期间(安装期间)创建过程,因为可以从提升的权限上下文运行安装程序。如果没有设置,则创建需要在部署期间运行的配置工具,该工具需要更高的权限,并执行初始部署过程。如果你不能这样做,基本上这意味着你不能这样做,所以你不应该一开始就这样做。谢谢你的回答。如果队列名称事先未知,是否有任何方法可以在不使用动态sql的情况下创建它?我对各种ServiceBroker语句都有这个问题(其中大多数语句不能作为准备语句/使用SqlCommands参数化)