我需要建立一个允许开发人员请求数据库紧急ID的系统。他们将被分配到一个名为“分析师”的角色,该角色将为他们提供一个下拉框,其中包含他们可以访问的数据库。他们将提交请求,并将生成一个临时的SQL登录并显示在屏幕上。登录名将具有一些提升的权限。登录将在12小时后删除。
我已经在ASP.NET上以SA的身份运行了整个过程,但现在我正在修改过程,以便使用应用程序连接字符串中的SQL登录来工作。
我试过一些方法让它工作,但遇到了障碍。
这是我的程序,它真正起作用。
USE [SQLEmergencyLoginRequest]
GO
/****** Object: StoredProcedure [dbo].[SQLELR_Login_CREATE] Script Date: 12/08/2009 14:48:29 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[SQLELR_Login_CREATE]
@SERVER VARCHAR(50),
@DATABASE VARCHAR(50),
@NTLOGIN VARCHAR(50),
@IR INT,
@LOGIN VARCHAR(50) OUTPUT,
@PWD VARCHAR(20) OUTPUT,
@NotifyDBA INT
WITH EXECUTE AS OWNER
AS
/*
Emergency_Access_Login_CREATE: Create Login/PWD, Create User, Create Role, Add User to Role, return Login/PWD.
*/
DECLARE @Random_Login_Extension VARCHAR(20)
DECLARE @sql VARCHAR(1000)
SET @Database = QUOTENAME(@Database);
BEGIN TRANSACTION
--CREATE LOGIN/PWD
EXEC dbo.random_password @Random_Login_Extension OUTPUT;
EXEC dbo.random_password @PWD OUTPUT;
SET @LOGIN = 'Emergency_Login_' + @Random_Login_Extension;
SET @sql= 'CREATE LOGIN [' + @LOGIN + ']' +
'WITH PASSWORD= ''' + @PWD + ''', DEFAULT_DATABASE=[master], ' +
'CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF';
EXEC(@sql);
--CREATE USER
DECLARE @User_Cmd VARCHAR(1000);
SET @User_Cmd = 'USE ' + @DATABASE + ';' +
'CREATE USER [' + @LOGIN + '] FOR LOGIN [' + @LOGIN + '];' +
'EXEC sp_addrolemember N''db_datareader'',''' + @LOGIN + ''';' +
'EXEC sp_addrolemember N''db_datawriter'',''' + @LOGIN + ''';' +
'EXEC sp_addrolemember N''db_ddladmin'',''' + @LOGIN + ''';';
EXEC (@User_Cmd);
INSERT INTO dbo.SQLELR_Emergency_Logins
([CreationTime]
,[NTLogin]
,[IR]
,[SERVER]
,[DATABASE]
,SQLLoginCreated)
VALUES
(GETDATE()
,@NTLOGIN
,@IR
,@SERVER
,@DATABASE
,@LOGIN)
DECLARE @MYBODY VARCHAR(500)
SET @MYBODY = @NTLOGIN + ' has created a temporary login in the ' + @Database + ' Database. The login name is ' + @LOGIN;
DECLARE @MYSUBJECT VARCHAR(500)
SET @MYSUBJECT = 'Emergency Login Creation ON server ' + @@SERVERNAME;
IF @NotifyDBA = 1
BEGIN
EXEC msdb.dbo.sp_notify_operator
@profile_name = 'SQLDBA',
@name = 'SQLDBA',
@subject = @MYSUBJECT,
@body = @MYBODY;
END
COMMIT TRANSACTION
我不希望应用程序帐户在每个数据库中都具有高度特权,因此我创建了另一个帐户,该帐户将进入每个数据库并
db_owner
. 明显地
sp_addrolemember
使用固定数据库角色需要一个数据库所有者才能工作,这就是为什么acct是
数据库所有者
. 我更喜欢安全管理,但似乎不可能。
回到问题上来-将execute as与动态代码一起使用不起作用。
只有在创建用户的每个数据库中创建一个存储过程,才能实现这一点吗?
我们这样做是因为我们想降低这台服务器的安全性,并从开发人员那里夺走db_所有者,这已经是多年来的惯例了。创建这个机制将满足他们唯一剩下的关于无法访问的抱怨。他们担心我们不会回答一页,他们将无法解决问题,所以这将解决这个问题。
当然,任何关于这里安全漏洞的建议也会受到赞赏。