2014-04-01 143 views
0

我有一個存儲過程可以合併到一個表中。我們稱之爲someSchema.UpsertSomeStuff(請注意,它不在dbo模式中)。我們稱之爲dbo.SomeStuff(注意它在dbo模式中)。授予存儲過程的權限

當我用數據讀取器/數據寫入器用戶調用存儲過程時,它工作正常。

但是,如果我授予將此存儲過程稱爲非常弱用戶(無數據編寫者或讀者權限)的權限,那麼它會告訴我無法選擇,插入或更新到dbo。 SomeStuff

我不想讓這個弱用戶訪問該表。我只想讓存儲過程有權訪問。

我嘗試使用WITH EXECUTE AS OWNER和它似乎工作,但後來我的同事開始收到此錯誤時,他試圖修改存儲過程:

無法執行的用戶MyUserNameHere',因爲它不存在或您沒有權限。

我對所有者和模式之間的差異有點困惑。但我認爲應該有一種方法可以完成這項工作,而無需將其與我的個人用戶帳戶綁定。

+0

看看['這裏'](http://stackoverflow.com/questions/19517251/sql-server-user-permissions-on-stored-procedure-and-underlying-tables) –

+0

OP是明確的不想讓這個用戶訪問該表。 – dean

回答

0

你需要的是簽署程序。

讓我在他的評論(SQL Server User Permissions on Stored Procedure and Underlying Tables)提供的鏈接M.Ali借用設置:

use Test 
go 
if exists (select * from sys.syslogins where name = 'UserA') 
    drop login UserA 
create login UserA with password = 'Welcome' 
if exists (select * from sys.syslogins where name = 'UserB') 
    drop login UserB 
create login UserB with password = 'Welcome' 
if exists (select * from sys.syslogins where name = 'UserC') 
    drop login UserC 
create login UserC with password = 'Welcome' 


if exists (select * from sys.tables where name = 'Customers' and schema_name(schema_id) = 'SchemaA') 
    drop table SchemaA.Customers 
if exists (select * from sys.schemas where name = 'SchemaA') 
    drop schema SchemaA 
if exists (select * from sys.sysusers where name = 'UserA') 
    drop user UserA 

if exists (select * from sys.tables where name = 'Orders' and schema_name(schema_id) = 'SchemaB') 
    drop table SchemaB.Orders 
if exists (select * from sys.procedures where name = 'GetCustomerOrderInfo' and schema_name(schema_id) = 'SchemaB') 
    drop procedure SchemaB.GetCustomerOrderInfo 
if exists (select * from sys.schemas where name = 'SchemaB') 
    drop schema SchemaB 
if exists (select * from sys.sysusers where name = 'UserB') 
    drop user UserB 

if exists (select * from sys.sysusers where name = 'UserC') 
    drop user UserC 

create user UserA for login UserA 
alter role db_owner add member UserA 
go 
create schema SchemaA authorization UserA 
go 
create user UserB for login UserB 
alter role db_owner add member UserB 
go 
create schema SchemaB authorization UserB 
go 
create user UserC for login UserC 

create table SchemaA.Customers (id int identity) 

create table SchemaB.Orders (id int identity, CustomerId int) 
go 
create procedure SchemaB.GetCustomerOrderInfo 
as 
select * 
from SchemaB.Orders o 
join SchemaA.Customers c 
on  c.id = o.CustomerId 
go 

這是設置,THX到Andomar。

我們可以給用戶C的過程的執行權限:

grant execute on SchemaB.GetCustomerOrderInfo to UserC 
execute as login = 'UserC' 
exec SchemaB.GetCustomerOrderInfo 
-- The SELECT permission was denied on the object 'Customers', database 'Test', schema 'SchemaA'. 
revert 

這還不夠好。我們所能做的就是在數據庫中創建一個證書,這個證書的數據庫用戶,給用戶相應的權限(在此示例中db_owner角色),然後用該證書籤名的過程:

create certificate cert_raiser 
    encryption by password = 'pGFD4bb925DGvbd2439587y' 
    with subject = 'raiser', 
    expiry_date = '01/01/2114'; 
go 

create user cert_user from certificate cert_raiser 
go 

alter role db_owner add member cert_user 
go 

add signature to SchemaB.GetCustomerOrderInfo 
    by certificate cert_raiser 
    with password = 'pGFD4bb925DGvbd2439587y'; 
go 

它應該現在工作好了。

要點:在證書上創建的用戶不能用作普通用戶,沒有用戶登錄,這不是安全問題;當我們添加一個簽名時,我們給該用戶的所有權限將被添加到執行過程的上下文中;如果我們改變程序,我們必須再次簽署。