在sql Server中新增供應用程式使用的帳號

伊谢尔伦
發布: 2016-12-03 11:10:58
原創
1063 人瀏覽過

在之前客戶諮詢案例中,很多客戶應用程式連接SQL Server直接用的就是SA帳號。如果對資料庫管理稍微嚴格一點的話,就不應該給應用程式這種權限,通常應用程式只需要進行增刪改查,而很少有DDL操作,因此配置帳號時應該遵循「最小權限分配」的原則僅僅賦予所需的權限。

    對應用程式來說,最小的權限通常就是給予讀取權限,寫入權限和執行預存程序權限。由於為了防止SQL注入導致的資料庫資訊洩漏,則還需要考慮拒絕帳號的檢視定義權限,但值得注意的是,如果拒絕了檢視定義的權限,則Bulk Insert會失敗。完整的權限定義如下:

ALTER ROLE [db_datareader] ADD MEMBER 用户名
ALTER ROLE [db_datawriter] ADD MEMBER 用户名
grant execute to 用户名
deny view definition to 用户名
登入後複製

   在SQL Server中,執行個體層級的是登入名,而資料庫層級的是使用者名,登入名稱在建立完成後可對應到特定的函式庫。因此我寫了一個完整的腳本,同時建立登入名,用戶,以及賦予對應的權限,腳本如下:

--创建用户的存储过程, 
--示例EXEC sp_CreateUser 'UserName','rw','DatabaseName' 
--EXEC sp_CreateUser 'tesefx','r','Test','0xE39CA97EBE03BB4CA5FF78E50374EEBB' 
CREATE PROC sp_CreateUser 
@loginName VARCHAR(50) , 
@IsWrite VarCHAR(3) , 
@DatabaseName VARCHAR(50), 
@Sid VARCHAR(100) ='1' 
AS 
PRINT('示例:EXEC sp_CreateUser ''UserName'',''rw'',''DatabaseName''') 
PRINT('示例:EXEC sp_CreateUser ''UserName'',''rwv'',''DatabaseName'',''0xE39CA97EBE03BB4CA5FF78E50374EEBB''') 
PRINT('r为只读权限,rw为读写权限,rwv为读写加View Definition权限') 
IF EXISTS ( SELECT name 
FROM sys.syslogins 
WHERE name = @loginName ) 
BEGIN 
PRINT N'登录名已存在,跳过创建登录名步骤' 
END 
ELSE 
BEGIN 
DECLARE @CreateLogin NVARCHAR(1000) 
DECLARE @pwd VARCHAR(50) 
PRINT @Sid 
SET @pwd=NEWID() 
IF(@sid='1') 
BEGIN 
SET @CreateLogin = 'CREATE LOGIN [' + @loginName + '] WITH PASSWORD=N''' 
+ @Pwd 
+ ''', DEFAULT_DATABASE=[master], CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF;' 
PRINT N'登录名已创建,密码为:'+@pwd 
END 
ELSE 
BEGIN 
SET @CreateLogin = 'CREATE LOGIN [' + @loginName + '] WITH PASSWORD=N''' 
+ @Pwd 
+ ''', DEFAULT_DATABASE=[master], CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF,sid='+@Sid+';' 
PRINT N'已经使用SID创建登录名:'+@loginName 
END 
EXEC (@CreateLogin) 
--DECLARE @sidtemp NVARCHAR(50) 
--SELECT @sidtemp=sid FROM sys.server_principals WHERE name=@loginName 
--PRINT(N'登录名为:'+@loginName+N' SID为: 0x'+CONVERT(VARCHAR(50), @sidtemp, 2) ) 
END 
DECLARE @DynamicSQL NVARCHAR(1000) 
--切换数据库上下文 
SET @DynamicSQL = N'Use [' + @DatabaseName + ']; ' + 'IF EXISTS(SELECT name FROM sys.database_principals WHERE name='''+@loginName+''') Begin Print(''用户名已存在,跳过创建用户名的步骤'') end else begin CREATE USER [' 
+ @loginName + '] FOR LOGIN ' + @loginName + ' end;IF (''' 
+ @IsWrite 
+ '''=''rw'' or ''' 
+ @IsWrite 
+ '''=''rwv'') BEGIN ALTER ROLE [db_datareader] ADD MEMBER ' + @loginName 
+ ';ALTER ROLE [db_datawriter] ADD MEMBER ' + @loginName 
+ '; END ELSE BEGIN ALTER ROLE [db_datareader] ADD MEMBER ' 
+ @loginName + '; 
ALTER ROLE db_datawriter DROP MEMBER ' 
+ @loginName + ' 
;End;grant execute to ' + @loginName + '; 
if(&#39;&#39;&#39;+@IsWrite+&#39;&#39;&#39;<>&#39;&#39;rwv&#39;&#39;) begin deny view definition to &#39; + @loginName + &#39;; end else begin grant view definition to &#39; + @loginName + &#39;; end&#39; 
EXEC (@DynamicSQL)
登入後複製

   該預存程序用於建立應用程式連接SQL Server所需的登入名,用戶以及對應權限,當使用者或登入名稱存在時也會跳過該步驟,使用該預存程序的範例如: 

EXEC sp_CreateUser &#39;UserName&#39;,&#39;rw&#39;,&#39;DatabaseNam&#39;
EXEC sp_CreateUser &#39;tesefx&#39;,&#39;r&#39;,&#39;Test&#39;,&#39;0xE39CA97EBE03BB4CA5FF78E50374EEBB&#39;
登入後複製

    上述執行的第一行是建立一個標準的帳號,帳號UserName,賦予對DatabaseNam的函式庫的讀寫權限,並傳回產生的GUID密碼。第二個預存程序是使用第四個參數sid建立登入名,由於在AlwaysOn或鏡像的環境中,兩端登入名稱需要有相同的SID,因此提供了在該情況下使用SID建立登入的方法。


相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!