SQL Server: bir kullanıcıya tablolarında değil görünümde seçme erişimi verin


11

Birkaç veritabanına sahip bir SQL Server 2012 örneğim var. Birinde tabloları bir veritabanından daha fazla seçen bir görünüm oluşturdum.

Bir kullanıcının bu görünümü seçmesini istiyorum, ancak tablolarını seçmemelidir. Görünüm tam olarak kullanıcı tabloları seçemediği için oluşturuldu.

Https://stackoverflow.com/questions/368414/grant-select-on-a-view-not-base-table ve http://msdn.microsoft.com/en-us/library/ms188676 adresini okudum . aspx ve hala çalışmıyor.

GRANT SELECT TABLE TO USERTüm tablolara bir işlemi yaparsam kullanıcı görünümü seçebilir. Ama herhangi bir masaya iptal edersem başarısız olur.

Bu yapılması kolay bir prosedür olmalı, ancak çalışmasını sağlamakta sorun yaşıyorum. Daha önce olduğunu gördüm (bir örneğin sahibi bana bir görünüme erişim verdi ve tablolarına yapmadı) ama bunu yapamıyorum veya nasıl olduğunu bilen birini bulamıyorum.

Birisi bana nasıl yapılacağına dair bir eğitim veya bir kod örneği verebilir mi?


Kullanıcı SELECTsgörünümünde mesaj aldığımda:

Nesne <TABLE>, veritabanı <DB>, şemada SELECT izni reddedildi dbo.

Bu tabloya seçim izni verirseniz, hata iletisi tablo adını görünümün okuduğu başka bir tabloya değiştirir.


Yorumlar uzun tartışmalar için değildir; bu görüşme sohbete taşındı .
Paul White 9

Yanıtlar:


21

Kullanıcıların görünümden seçim yapmasını istiyorsanız, neden tabloya veriyorsunuz? "İptal" demekle açıkça iptal / reddetmek mi? Reddet, hibe geçersiz kılar, böylece sorununuz var ... bunu , görünüme hibe ekleyerek ve tablolarda herhangi bir şekilde bir şey yapmadan yapabilmeniz gerekir .

İşte SELECTaçık bir şekilde masaya verilmemiş ancak görünümde olan hızlı bir örnek . Kullanıcı tablodan değil görünümden seçim yapabilir.

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;

Bu varsayımın fooşema veya veritabanındaki açık izinlerle veya rol veya grup üyeliği yoluyla yükseltilmiş ayrıcalıklar verilmediğini unutmayın .

Birden çok veritabanında tablolar kullandığınız için (üzgünüm başlangıçta bu ilk cümlenin sonunu kaçırdım), ayrıca görünümün bulunmadığı veritabanındaki tablolarda açık hibelere de ihtiyacınız olabilir. Tablolara seçim vermekten kaçınmak için, her veritabanında bir görünüm oluşturabilir ve sonra görünümlere katılabilirsiniz.

İki veritabanı ve bir giriş oluşturun:

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

Veritabanında d1bir kullanıcı oluşturun, ardından bir tablo ve o tabloya karşı basit bir görünüm oluşturun. Kullanıcıya yalnızca görünüme karşı seçim izni verin :

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

Şimdi, ikinci veritabanında, kullanıcıyı oluşturun, sonra başka bir tablo ve bu tabloyu görünüme birleştiren bir görünüm oluşturun d1. Yalnızca görünüme seçme izni verme.

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

Şimdi yeni bir sorgu penceresi başlatın ve oturum açma için kimlik bilgilerini değiştirin blat( EXECUTE ASburada çalışmaz). Sonra her iki veritabanı bağlamında aşağıdakileri çalıştırın ve iyi çalışması gerekir:

SELECT id FROM d1.dbo.v2;

Bunların her ikisi de Msg 229 hataları vermelidir:

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

Sonuçlar:

Msg 229, Seviye 14, Durum 5, Satır 1
't1' nesnesi, 'd1' veritabanı, 'dbo' şeması üzerinde SELECT izni reddedildi.
Msg 229, Seviye 14, Durum 5, Satır 3
't2' nesnesi, 'd2' veritabanı, 'dbo' şeması üzerinde SELECT izni reddedildi.


1

Topluluk wiki yanıtı aslen yazar tarafından soruya eklendi:

Ben de öyle yaptım:

  1. DB A'da, içindeki tüm tabloları birleştirerek bir görünüm oluşturdu.
  2. Verilen SELECTonun tablolarına söz konusu görünüm üzerinde kullanıcıya erişim ve NOT. Kullanıcı tabloları değil görünümü sorgulayabildi.
  3. DB B'de bir görünüm oluşturuldu ve bu DB'deki tabloları DB A'daki görünümle birleştirdi.
  4. Verilen SELECTDEĞİL herhangi tabloya da bu ikinci görünümde kullanıcıya erişim, vb. Kullanıcı bu son görünümü başarıyla sorgulayabildi ve verileri görebildi.

Bence bir görünüm kullanıcının doğrudan erişim yok ama diğer DB tablolarda bunu yapamam DB kendi tabloları sorgulamak mümkün olduğunu düşünüyorum. En azından işe yaradı.


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.