sqlserver簡便建立用戶並受權

    不少研發人員程序鏈接SQL Server直接用的就是SA賬號。若是對數據庫管理稍微嚴格一點的話,就不該該給應用程序這種權限,一般應用程序只須要進行增刪改查,而不多有DDL操做,所以配置賬號時應該遵循「最小權限分配」的原則僅僅賦予所需的權限。sql

    對於應用程序來講,最小的權限一般就是就是給予讀權限,寫權限和執行存儲過程權限。因爲爲了防止SQL注入致使的數據庫信息泄漏,則還須要考慮拒絕賬號的查看定義權限,但值得注意的是,若是拒絕了查看定義的權限,則Bulk Insert會失敗。完整的權限定義以下:數據庫

ALTER ROLE [db_datareader] ADD MEMBER 用戶名
ALTER ROLE [db_datawriter] ADD MEMBER 用戶名
grant execute to 用戶名
deny view definition to 用戶名

   在SQL Server中,實例級別的是登陸名,而數據庫級別的纔是用戶名,登陸名在建立完成後可映射到具體的庫。所以我寫了一個完整的腳本,同時建立登陸名,用戶,以及賦予對應的權限,腳本以下:code

--建立用戶的存儲過程, 

--示例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('''+@IsWrite+'''<>''rwv'') begin deny view definition to ' + @loginName + '; end else begin grant view definition to ' + @loginName + '; end' 

EXEC (@DynamicSQL) 

   該存儲過程用於建立應用程序鏈接SQL Server所需的登陸名,用戶以及對應權限,當用戶或登陸名存在時還會跳過該步驟,使用該存儲過程的示例如:
server

EXEC sp_CreateUser 'UserName','rw','DatabaseNam'
EXEC sp_CreateUser 'tesefx','r','Test','0xE39CA97EBE03BB4CA5FF78E50374EEBB' 

    上述執行的第一行是建立一個標準的賬號,帳戶名UserName,賦予對DatabaseNam的庫的讀寫權限,並返回生成的GUID密碼。第二個存儲過程是使用第四個參數sid建立登陸名,因爲在AlwaysOn或鏡像的環境中,兩端登陸名須要有相同的SID,所以提供了在該狀況下使用SID建立登陸名的辦法。ip

 

    若是須要,能夠將該存儲過程按照本身的須要去修改。ci

相關文章
相關標籤/搜索