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

2021-09-22 12:12:53 字數 3578 閱讀 9432

在之前客戶諮詢案例中,很多客戶應用程式連線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('''+@iswrite+'''<>''rwv'') begin deny view definition to ' + @loginname + '; end else begin grant view definition to ' + @loginname + '; end' 

exec (@dynamicsql) 

該儲存過程用於建立應用程式連線sql server所需的登入名,使用者以及對應許可權,當使用者或登入名存在時還會跳過該步驟,使用該儲存過程的示例如: 

exec sp_createuser 'username','rw','databasenam'

exec sp_createuser 'tesefx','r','test','0xe39ca97ebe03bb4ca5ff78e50374eebb' 

上述執行的第一行是建立乙個標準的帳號,賬戶名username,賦予對databasenam的庫的讀寫許可權,並返回生成的guid密碼。第二個儲存過程是使用第四個引數sid建立登入名,由於在alwayson或映象的環境中,兩端登入名需要有相同的sid,因此提供了在該情況下使用sid建立登入名的辦法。

如果需要,可以將該儲存過程按照自己的需要去修改。

分類: sql server安全

在sqlserver中with nolock 詳解

在查詢語句中使用 nolock 和 readpast 處理乙個資料庫死鎖的異常時候,其中乙個建議就是使用 nolock 或者 readpast 有關 nolock 和 readpast的一些技術知識點 對於非銀行等嚴格要求事務的行業,搜尋記錄中出現或者不出現某條記錄,都是在可容忍範圍內,所以碰到死鎖...

在SQLSERVER中讀取Oracle中的資料

在sqlserver 中讀取oracle 中的資料 作者 林清清日期 2006 2 13 要求 在ms sql server2000 資料庫中連線並讀取 oracle9i 資料庫中的資料.假設 目標oracle 資料庫相關引數如下 table name table1 oracle ip 172.18...

在SQLSERVER中建立DBLINK

配置sqlserver資料庫的dblink exec sp addlinkedserver server was sms srvproduct provider sqloledb datasrc 10.131.20.100 exec sp addlinkedsrvlogin was sms fals...