列错误返回NULL而不是权限被拒绝

时间:2017-10-01 17:31:42

标签: sql-server

我有一个表,其中包含使用列级限制的特权数据 权限。我想有单一的查询返回来自的数据 表。如果用户具有权限,则应返回数据但返回 如果用户没有权限,则为NULL。

sa授予此权限:

use WorkDB
GRANT SELECT ON dbo.[User](Name)  TO [Ali];  
go

Ali希望运行此代码:

SELECT [ID],[Name] FROM [WorkDB].[dbo].[User]

错误: 对象'User',数据库'WorkDB',schema'dbo'的列'ID'上的SELECT权限被拒绝。

2 个答案:

答案 0 :(得分:4)

这是不可能的。

除非用户对该列具有权限,否则SQL Server将不允许在SELECT列表中引用该列。

我有一些希望this approach for a missing column可能会有用,但遗憾的是它没有。

SQL Server仍然会将列解析为基表并抱怨缺少的权限,而不是将其解析为外部查询中的同一命名列。

您可以直接拒绝表上的所有选择权限,而不是拒绝表上的列级权限,而是创建VIEW。然后让所有SELECT访问权限通过。使用CASE表达式检查用户名/角色成员身份。例如

CREATE VIEW dbo.vUser
AS
  SELECT CASE
           WHEN USER_NAME() <> 'Ali'
             THEN [ID]
         END AS [ID],
         [Name]
  FROM   [dbo].[User] 

视图需要与表所有者链相同才能使用。

答案 1 :(得分:0)

    USE master
GO

CREATE DATABASE SecurityTest;
GO

-- Creates the master key.
-- The key is encrypted using the password "23987hxJ#KL95234nl0zBe."  
CREATE MASTER KEY ENCRYPTION BY PASSWORD = '23987hxJ#KL95234nl0zBe'; 
GO


SELECT * FROM sys.symmetric_keys WHERE name = '##MS_DatabaseMasterKey##';
GO

USE SecurityTest;
GO
CREATE CERTIFICATE CertificateSecurityTestDb
WITH SUBJECT = 'Encrypted Data';
GO

-- Create symmetric Key

CREATE SYMMETRIC KEY SymmetricKeySecurityTestDb WITH ALGORITHM = AES_128 ENCRYPTION BY CERTIFICATE CertificateSecurityTestDb;
GO

CREATE TABLE TblTestTable(id int NOT NULL, CustomerFullName NVARCHAR(50) NOT NULL, Price int DEFAULT(0),PriceEncrypted VARBINARY(500))

INSERT INTO TblTestTable(id,CustomerFullName,Price)
VALUES
(1,'ibrahim Sezen',100),(2,'Gözde Özarpacı',200),(3,'Vedat Kürkçü',300),(4,'Kaan Özdemir',50),(5,'Sema Kocabekirler',70)

GO

-- Opens the symmetric key for use
OPEN SYMMETRIC KEY SymmetricKeySecurityTestDb
DECRYPTION BY CERTIFICATE CertificateSecurityTestDb;
GO
UPDATE TblTestTable
SET PriceEncrypted = EncryptByKey (Key_GUID('SymmetricKeySecurityTestDb'),CAST(Price AS varchar))
FROM TblTestTable;
GO
-- Closes the symmetric key
CLOSE SYMMETRIC KEY SymmetricKeySecurityTestDb;
GO


-- Test 
OPEN SYMMETRIC KEY SymmetricKeySecurityTestDb
DECRYPTION BY CERTIFICATE CertificateSecurityTestDb;
GO
-- Now list the original ID, the encrypted ID 
SELECT id CustomerFullName, Price ,PriceEncrypted,
CONVERT(varchar, DecryptByKey(PriceEncrypted)) AS 'Sifresiz Kagit Maliyeti'
FROM TblTestTable

 -- Close the symmetric key
CLOSE SYMMETRIC KEY SymmetricKeySecurityTestDb;
GO


--CREATE USERS

CREATE USER [DomainName\dummyuser] FOR LOGIN [DomainName\dummyuser] WITH DEFAULT_SCHEMA=[db_datareader]
GO
CREATE USER [DomainName\ogulcanc] FOR LOGIN [DomainUser\ogulcanc] WITH DEFAULT_SCHEMA=[db_datareader]
GO

-- Grant Dummy User ...
GRANT VIEW DEFINITION ON Certificate::CertificateSecurityTestDb TO [DomainName\dummyuser];
GO
GRANT VIEW DEFINITION ON SYMMETRIC KEY::SymmetricKeySecurityTestDb TO [DomainName\dummyuser];
GO
GRANT VIEW DEFINITION ON SYMMETRIC KEY::SymmetricKeySecurityTestDb TO [DomainName\dummyuser];
GO



-- Test 2
EXECUTE AS USER  = 'DomainName\ogulcanc'
GO
BEGIN TRY
    OPEN SYMMETRIC KEY SymmetricKeyTestDb
    DECRYPTION BY CERTIFICATE CertificatetestDb;

    SELECT id CustomerFullName, Price ,PriceEncrypted,
    CONVERT(varchar, DecryptByKey(PriceEncrypted)) AS 'Price DecryptByKey'
    FROM TblTestTable

    -- Close the symmetric key
    CLOSE SYMMETRIC KEY SymmetricKeyTestDb;
END TRY
BEGIN CATCH

    SELECT id CustomerFullName, Price ,PriceEncrypted,
    CONVERT(varchar, DecryptByKey(PriceEncrypted)) AS 'Price DecryptByKey'
    FROM TblTestTable

END CATCH

GO

REVERT;

-- TEST 2 
-----------------
-- Test 2
EXECUTE AS USER = 'DomainName\dummyuser'
GO
BEGIN TRY
    OPEN SYMMETRIC KEY SymmetricKeySecurityTestDb
    DECRYPTION BY CERTIFICATE CertificateSecurityTestDb;

    SELECT id CustomerFullName, Price ,PriceEncrypted,
    CONVERT(varchar, DecryptByKey(PriceEncrypted)) AS 'Price DecryptByKey'
    FROM TblTestTable

    -- Close the symmetric key
    CLOSE SYMMETRIC KEY SymmetricKeyTestDb;
END TRY
BEGIN CATCH

        SELECT id CustomerFullName, Price ,PriceEncrypted,
        CONVERT(varchar, DecryptByKey(PriceEncrypted)) AS 'Price DecryptByKey'
        FROM TblTestTable

END CATCH

GO