[英]How do I determine if I have execute permissions on a DB programatically?
我有一個Windows服務,該服務要求對SQL Server 2005 DB具有執行權限。 在啟動時,我檢查是否可以連接到數據庫並在無法連接時停止該服務。 我還想檢查一下是否可以使用該連接執行存儲過程。 有沒有一種方法可以執行此操作而無需實際嘗試執行sproc並查看異常(如果發生)?
SQL 2005及HAS_PERM_BY_NAME
,您可以使用HAS_PERM_BY_NAME
檢查任何權限:
SELECT HAS_PERMS_BY_NAME('sp_foo', 'OBJECT', 'EXECUTE');
您可以運行如下查詢:
SELECT
o.NAME,COALESCE(p.state_desc,'?permission_command?')+' '+COALESCE(p.permission_name,'?permission_name?')+' ON ['+SCHEMA_NAME(o.schema_id)+'].['+COALESCE(o.Name,'?object_name?')+'] TO ['+COALESCE(dp.Name,'?principal_name?')+']' COLLATE SQL_Latin1_General_CP1_CI_AS AS GrantCommand
FROM sys.all_objects o
INNER JOIN sys.database_permissions p ON o.OBJECT_ID=p.major_id
LEFT OUTER JOIN sys.database_principals dp ON p.grantee_principal_id = dp.principal_id
where p.state_desc='GRANT' AND p.permission_name='EXECUTE'
AND o.NAME='YourProcedureName'
AND dp.Name='YourSecurityName'
...並刪除Grant命令的格式,該格式僅供參考
這些也很好...
SELECT * FROM fn_my_permissions('YourTable', 'OBJECT')
SELECT * FROM fn_my_permissions('YourProcedure', 'OBJECT')
SELECT * FROM fn_my_permissions (NULL, 'DATABASE')
SELECT * FROM fn_my_permissions(NULL, 'SERVER')
要查看其他人擁有哪些權限,可以執行以下操作:
EXECUTE AS user = 'loginToTest'
GO
PRINT 'SELECT permissions on tables:'
SELECT
HAS_PERMS_BY_NAME( QUOTENAME(SCHEMA_NAME(schema_id))+'.' + QUOTENAME(name)
,'OBJECT','SELECT'
) AS have_select
, *
FROM sys.tables;
PRINT 'EXECUTE permissions on stored procedures:'
SELECT
HAS_PERMS_BY_NAME( QUOTENAME(SCHEMA_NAME(schema_id)) + '.' + QUOTENAME(name)
,'OBJECT', 'EXECUTE') AS have_execute
, *
FROM sys.procedures;
GO
REVERT;
GO
該答案的第一部分顯示了如何在T-SQL中檢查權限,第二部分給出了一個如何在Entity Framework中使用它的示例(請注意,EF版本之間存在差異-給出的示例為EF 4,但是可以輕松更改為較新版本):
第一部分(SQL):
我正在使用以下T-SQL腳本檢查權限。 它首先檢查您是否具有任何權限,然后檢查SP的執行權限,最后選擇表的權限。 請參閱此鏈接以獲取更多信息。
-- 1. Do I have any permissions?
SELECT HAS_PERMS_BY_NAME(db_name(), 'DATABASE', 'ANY') DoIHaveAnyRights;
-- 2. create list of schemas
declare @SchemaList table (schema_id int, name nvarchar(max));
PRINT 'Schemas regarded:'
insert into @SchemaList
select distinct schema_id, name FROM sys.schemas
where name in ('dbo') -- enter the schemas you like to check comma-separated
SELECT s.name, s.schema_id FROM sys.schemas s
join @SchemaList sl on s.schema_id=sl.schema_id
-- 3. check execute permissions
PRINT 'EXECUTE permissions on stored procedures:'
SELECT
HAS_PERMS_BY_NAME(QUOTENAME(SCHEMA_NAME(t.schema_id)) + '.' + QUOTENAME(t.name)
,'OBJECT', 'EXECUTE') AS [have execute]
,'['+s.name +'].['+ t.name+']' as [object]
--, *
FROM sys.procedures t
join @SchemaList s on t.schema_id=s.schema_id
order by s.name, t.name;
-- 4. check select permissions
PRINT 'SELECT permissions on tables:'
SELECT
HAS_PERMS_BY_NAME(QUOTENAME(SCHEMA_NAME(t.schema_id))+'.' + QUOTENAME(t.name)
,'OBJECT','SELECT') AS [have select]
,'['+s.name +'].['+ t.name+']' as [object]
--, *
FROM sys.tables t
join @SchemaList s on t.schema_id=s.schema_id
order by s.name, t.name;
以羅斯文數據庫為例,這將為您提供以下結果:
請注意 ,您可以配置在步驟2中考慮的模式。如果不需要檢查一組有限的模式,則只需注釋掉insert into @SchemaList
語句中的where
子句即可獲取所有模式。
第二部分(實體框架):
在本節中,我想向您展示如何將結果獲取到Entity Framework中。 假設您要在使用LINQ查詢中的任何表之前檢查是否擁有任何權限。 看一下這個例子(為簡單起見,我已經在LinqPad中完成了它,請在運行它之前通過F4添加System.Data.Entity.dll
及其名稱空間):
void Main()
{
var dc=this;
var sql="SELECT TOP 1 "
+ "HAS_PERMS_BY_NAME(db_name(), 'DATABASE', 'ANY') DoIHaveAnyRights;";
var result=dc.ExecuteStoreQuery<Rights>(sql);
if (result1.DoIHaveAnyRights==1)
{
Console.WriteLine("OK"); // ok
}
else
{
// no rights: Show error etc.
Console.WriteLine("No rights"); // ok
}
}
public class Rights
{
public Int32 DoIHaveAnyRights { get; set; }
}
同樣,您可以使用答案第一部分中的查詢,例如:
var sql="select top 1 case when cnt.NoRightsCount=0 then 1 else 0 end "
+"as DoIHaveAnyRights "
+"from (SELECT count(1) NoRightsCount FROM sys.procedures t "
+"where HAS_PERMS_BY_NAME("
+"QUOTENAME(SCHEMA_NAME(t.schema_id)) + '.' + QUOTENAME(t.name)"
+",'OBJECT', 'EXECUTE')<>1) cnt";
此查詢將檢查數據庫中是否有您無權執行的存儲過程-在這種情況下,返回值將為result1.DoIHaveAnyRights!=1
。
我認為您已經明白了,並嘗試了各種可能性:請記住,EF需要訪問您要映射到的所有數據庫表,存儲過程等-您可以在訪問它們之前使用上面的代碼進行檢查。 不幸的是,目前沒有更簡單的方法可以做到這一點。
您將必須具有訪問數據庫的DataDictionary的權限,並對它運行查詢以確定登錄帳戶所擁有的權限。 這將因數據庫而異。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.