SQLSERVER 2005 開始 提供的對存儲過程簽名 (signature) 是我非常喜歡的。 如果我們要編寫一個存儲過程 , 執(zhí)行該存儲過程里的代碼需要權(quán)限 P, 并且我們想要用戶 Alice 可以執(zhí)行這個存儲過程,但是我們不想將權(quán)限 P 直接賦予給用戶 Alice , 我們可以用證書 (
sqlserver 2005開始提供的對存儲過程簽名(signature)是我非常喜歡的。
如果我們要編寫一個存儲過程,執(zhí)行該存儲過程里的代碼需要權(quán)限P,并且我們想要用戶Alice可以執(zhí)行這個存儲過程,但是我們不想將權(quán)限P直接賦予給用戶Alice,我們可以用證書(certificate)對這個存儲過程進(jìn)行簽名來完成這一需求:
a)????? 如果P是一個級別的權(quán)限,那我們可以在相應(yīng)的中創(chuàng)建一個證書,使用證書創(chuàng)建一個用戶(user),然后將權(quán)限p授權(quán)給這個用戶
b)????? 如果P是一個級別的權(quán)限,那我們能要在master數(shù)據(jù)庫中創(chuàng)建一個證書,使用證書創(chuàng)建一個登錄(login),然后將權(quán)限P授權(quán)給這個登錄
?簽名之后,存儲過程就會在執(zhí)行期間獲得權(quán)限P,而我們僅僅授予了Alice執(zhí)行這個存儲過程的權(quán)限。
???? 如果我們既需要服務(wù)器級別的權(quán)限,又需要數(shù)據(jù)庫級別的權(quán)限,那么我們既要創(chuàng)建用戶,又要創(chuàng)建登錄。下面列出步驟:
1)????? 在數(shù)據(jù)庫中創(chuàng)建證書
2)????? 創(chuàng)建一個用戶(user)并映射到這個證書
3)????? 將數(shù)據(jù)庫級別的權(quán)限授予這個用戶
4)????? 備份這個證書
5)????? 在master數(shù)據(jù)庫中還原這個證書
6)????? 創(chuàng)建一個登錄(login),并將登錄映射到證書
7)????? 將服務(wù)器級別的權(quán)限授予給這個登錄
?我們也可以先在master數(shù)據(jù)庫中創(chuàng)建證書,然后再將其還原到用戶alice工作的數(shù)據(jù)庫。也就是證書的創(chuàng)建順序并不重要,重要的是master數(shù)據(jù)庫中的證書一定要和用戶數(shù)據(jù)庫中的相同。
下面是演示:
— 目的
— 展示如何用證書簽名一個存儲過程,
?—并授予證書相應(yīng)的權(quán)限
?create database demo;
?use demo;
??
?— 創(chuàng)建一個存儲過程,該過程會創(chuàng)建一個主體(包含登錄和用戶)
— 這需要服務(wù)器級別的ALTER ANY LOGIN 權(quán)限
— 和數(shù)據(jù)庫級別的 ALTER ANY USER 權(quán)限
create procedure sp_CreatePrincipal
?????? @name varchar(256),
?????? @password varchar(128)
as
??? declare @sqlcmd varchar(2000);
??
????begin tran;
??
????— create login
??? set @sqlcmd = ‘create login ‘ + quotename(@name) + ‘ with password = ‘ + quotename(@password, ””);
??? exec (@sqlcmd);
??? if @@error 0
????begin
???????rollback tran;
?????? print ‘Cannot create login’
?????? return;
??? end