.net SQL Server通过集成登录提升了权限
我有一个在IIS中运行的应用程序,它使用windows集成身份验证连接到SQL Server 2008 R2实例。此应用程序使用一组存储过程在数据库中执行简单的读/写操作。对于这种登录/用户组合,我可以很好地限制SQL server中的权限 但对于应用程序的一小部分,我需要“提升”/数据库中更强大的权限。。。例如,创建/删除事件通知,并可能创建队列和代理服务 所以基本上我有一个进程,代码在连接到SQL server的同一个用户帐户下运行,我需要两组不同的权限。。。一个连接具有非常有限的权限,一个连接具有更强大的权限 我想使用windows集成身份验证。。。使用两个用户/密码组合的sql身份验证不是一个选项 有没有推荐的方法来实现这一点.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的同一个用户帐户下运行,我需要两组不同的权限。。。一个连接具有非常有限的权限,一个
- 在应用程序代码中,使用集成安全性从模拟上下文(不同的用户帐户/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参数化)