SQL Server : 테이블이 아닌 뷰에서 사용자에게 선택 액세스 권한 부여


11

몇 개의 데이터베이스가있는 SQL Server 2012 인스턴스가 있습니다. 그중 하나에서 데이터베이스 이상에서 테이블을 선택하는 뷰를 만들었습니다.

사용자가 해당보기를 선택할 수 있기를 원하지만 테이블을 선택해서는 안됩니다. 사용자가 테이블을 선택할 수 없기 때문에 뷰가 정확하게 작성되었습니다.

/programming/368414/grant-select-on-a-view-not-base-tablehttp://msdn.microsoft.com/en-us/library/ms188676을 읽었습니다 . aspx 및 여전히 작동하지 않습니다.

내가 할 경우 GRANT SELECT TABLE TO USER모든 테이블에, 사용자는 뷰를 선택 할 수 있습니다. 그러나 테이블을 취소하면 실패합니다.

이것은 쉬운 절차이지만, 작동시키는 데 어려움이 있습니다. 이전에 발생한 일을 보았습니다 (인스턴스 소유자가보기에 액세스하고 테이블에 액세스하지 못했습니다).하지만 할 수 없거나 방법을 알고있는 사람을 찾을 수 없습니다.

누군가 나에게 그것을 수행하는 방법에 대한 자습서 또는 코드 예제를 제공 할 수 있습니까?


사용자 SELECTs가보기를하면 메시지가 나타납니다.

개체 <TABLE>, 데이터베이스 <DB>, 스키마 에 대한 SELECT 권한이 거부되었습니다 dbo.

해당 테이블에 select를 부여하면 오류 메시지가 테이블 이름을 뷰가 읽는 다른 테이블로 변경합니다.


의견은 긴 토론을위한 것이 아닙니다. 이 대화는 채팅 으로 이동 되었습니다 .
Paul White 9

답변:


21

사용자가보기에서 선택하도록하려면 왜 테이블에 권한을 부여합니까? "취소"란 명시 적으로 취소 / 거부한다는 의미입니까? 거부는 권한 부여를 대체하므로 문제점이 있습니다 .보기에 권한 부여 추가 하고 테이블에서 아무 것도 수행하지 않으면 서이를 수행 할 수 있습니다.

다음 SELECT은 테이블에 명시 적으로 부여되지 않았지만 뷰에 있는 간단한 예 입니다. 사용자는 뷰에서 선택할 수 있지만 테이블에서는 선택할 수 없습니다.

CREATE USER foo WITHOUT LOGIN;
GO
CREATE TABLE dbo.a(id INT);
CREATE TABLE dbo.b(id INT);
GO
CREATE VIEW dbo.v 
AS 
  SELECT a.id FROM a INNER JOIN b ON a.id = b.id;
GO
GRANT SELECT ON dbo.v TO foo;
GO
EXECUTE AS USER = N'foo';
GO
-- works:
SELECT id FROM dbo.v;
GO
-- Msg 229, SELECT denied:
SELECT id FROM dbo.a;
GO
REVERT;

foo이는 스키마 나 데이터베이스에 대한 명시 적 권한이나 역할 또는 그룹 멤버 자격을 통해 상승 된 권한이 부여되지 않았다고 가정합니다 .

여러 데이터베이스에서 테이블을 사용하고 있기 때문에 (처음에는 첫 번째 문장의 끝을 놓쳤습니다) 뷰가 존재하지 않는 데이터베이스의 테이블에 대한 명시적인 권한이 필요할 수도 있습니다. 테이블에 select를 부여하지 않기 위해 각 데이터베이스에 뷰를 만든 다음 뷰를 조인 할 수 있습니다.

두 개의 데이터베이스와 로그인을 작성하십시오.

CREATE DATABASE d1;
GO
CREATE DATABASE d2;
GO
USE [master];
GO
CREATE LOGIN blat WITH PASSWORD = 'x', CHECK_POLICY = OFF;
GO

database d1에서 사용자를 만든 다음 테이블과 해당 테이블에 대한 간단한 뷰를 만듭니다. 보기에 대해서만 사용자에게 선택 권한을 부여하십시오 .

USE d1;
GO
CREATE USER blat FROM LOGIN blat;
GO
CREATE TABLE dbo.t1(id INT);
GO
CREATE VIEW dbo.v1
AS
  SELECT id FROM dbo.t1;
GO
GRANT SELECT ON dbo.v1 TO blat;
GO

이제 두 번째 데이터베이스에서 사용자를 작성한 다음 다른 테이블과 해당 테이블을의 뷰에 결합하는 뷰를 작성하십시오 d1. 보기에만 선택 권한을 부여하십시오.

USE d2;
GO
CREATE USER blat FROM LOGIN blat;
GO
CREATE TABLE dbo.t2(id INT);
GO
CREATE VIEW dbo.v2
AS
  SELECT v1.id FROM dbo.t2 
    INNER JOIN d1.dbo.v1 AS v1
    ON t2.id = v1.id;
GO
GRANT SELECT ON dbo.v2 TO blat;
GO

이제 새 쿼리 창을 시작하고 로그인 자격 증명을 변경하십시오 blat( EXECUTE AS여기서는 작동하지 않음). 그런 다음 데이터베이스의 컨텍스트에서 다음을 실행하면 정상적으로 작동합니다.

SELECT id FROM d1.dbo.v2;

이 모두 메시지 229 오류를 생성해야합니다.

SELECT id FROM d1.dbo.t1;
GO
SELECT id FROM d2.dbo.t2;

결과 :

메시지 229, 수준 14, 상태 5, 줄 1
개체 't1', 데이터베이스 'd1', 스키마 'dbo'에 대한 SELECT 권한이 거부되었습니다.
메시지 229, 수준 14, 상태 5, 줄 3
개체 't2', 데이터베이스 'd2', 스키마 'dbo'에 대한 SELECT 권한이 거부되었습니다.


1

커뮤니티 위키 답변은 원래 작성자가 질문에 추가했습니다.

이것이 내가 한 일입니다.

  1. 모든 테이블을 조인하여 DB A에 뷰를 작성했습니다.
  2. SELECT해당 테이블의 사용자가 아닌 해당 뷰의 사용자에게 액세스 권한이 부여 되었습니다. 사용자는 테이블이 아닌 뷰를 쿼리 할 수있었습니다.
  3. 이 DB의 테이블을 DB A의 뷰와 결합하여 DB B에 뷰를 작성했습니다.
  4. SELECT이 두 번째보기에서 사용자에게 액세스 권한이 부여 되며 테이블에는 액세스 할 수 없습니다. 사용자는이 최종 뷰를 쿼리하고 데이터를 볼 수있었습니다.

뷰가 사용자가 직접 액세스 할 수는 없지만 다른 DB의 테이블에서는 수행 할 수 없다는 DB의 테이블을 쿼리 할 수있는 것이 이상하다고 생각합니다. 적어도 효과가있었습니다.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.