Tek bir görünüme erişimi olan bir kullanıcı nasıl eklenir?


14

MSSQL Server Management Studio 2008 ile çalışıyorum ve veri mutabakatı için üçüncü bir tarafa bir görünüm ortaya koymak gerekiyor. Uygun görünümü oluşturdum ancak bir kullanıcı oluşturma ve bu kullanıcıya görünümden seçim yapmak için uygun izinleri verme konusunda sorun yaşıyorum.

Bir giriş ve kullanıcı oluşturmak için sihirbazları izledim ve ardından hibe kutusunu seçmek için işaretli durumdayken Güvenli Görünümü bölümüne görünümümü ekledim. Her şey iyi görünüyordu ama ben bu kullanıcı olarak giriş ve "MyViewName" seçin * "yapmaya çalıştığımda bana seçme izni reddedildi söyledi.

Sadece kullanıcıyı yeniden yarattım (bu sefer sihirbaz yerine sadece SQL kullanarak) ve açıkça seçme izinleri verdim ve şimdi bana hata veriyor: Msg 916, Level 14, State 1, Line 2 The server principal "username" is not able to access the database "unrelated_db" under the current security context.(neden ilgisiz veritabanına erişmeye çalıştığını bilmiyorum ...)

Buradan nereye gideceğimi gerçekten bilmiyorum. Yine, temelde ihtiyacım olan tek şey, veritabanımıza bağlanmaları ve bu görünümden seçim yapmaları için üçüncü tarafa verebileceğim bir kullanıcı oluşturmaktır.


3
Görünüm diğer veritabanlarındaki taban tablolarına başvuruda bulunuyor mu? Eğer öyleyse, sahiplik zinciriyle uğraşmak zorunda kalacaksınız. Ayrıca, veritabanı bağlamının istediğiniz veritabanına ayarlanmış olduğundan emin olun.
Thomas Stringer

Bir görünümün bağımlılıklarını görmenin bir yolu var mı? Yani, bildiğim kadarıyla, görünümdeki her şey ana veritabanında bulunmalıdır . Görünüm yalnızca üç alan, ikisi ödeme ayrıntıları tablosundan ve biri de hesap ayrıntıları tablosuna katılmadan geliyor, ancak her iki tablo da aynı veritabanında (ve görünümle aynı veritabanında).
velojason

Yanıtlar:


16

Lütfen bunun için kullanıcı arayüzünü kullanmayın. Bu kafa karıştırıcı bir karmaşa.

Bana sadece bir görünümden seçim yapma izni olan belirli bir giriş için veritabanında bir kullanıcı oluşturmak gibi. Yani, zaten giriş oluşturduğunuzdan:

USE your_db;
GO
CREATE USER username FROM LOGIN username;
GO
GRANT SELECT ON dbo.MyViewName TO username;
GO

Burada DÜZENLE bahsettiğiniz hataya yol açacak bir komut dosyası örneğidir.

İlk olarak, unrelated_db içinde bir tablo oluşturun:

CREATE DATABASE unrelated_db;
GO
USE unrelated_db;
GO
CREATE TABLE dbo.foo(bar INT);
GO

Şimdi nispeten kısıtlı bir giriş oluşturun:

USE [master];
GO
CREATE LOGIN username WITH PASSWORD='foo', CHECK_POLICY = OFF;
GO

Şimdi görünümün yaşayacağı bir veritabanı oluşturun ve girişi kullanıcı olarak ekleyin:

CREATE DATABASE velojason;
GO
USE velojason;
GO
CREATE USER username FROM LOGIN username;
GO

Şimdi diğer veritabanındaki tabloya başvuracak bir işlev ve diğer tablo ile eşanlamlı oluşturun:

CREATE FUNCTION dbo.checkbar()
RETURNS INT
AS 
BEGIN
    RETURN 
    (
      SELECT TOP (1) bar 
        FROM unrelated_db.dbo.foo 
        ORDER BY bar
    );
END
GO
CREATE SYNONYM dbo.foo FOR unrelated_db.dbo.foo;
GO

Şimdi yerel bir tablo oluşturun:

CREATE TABLE dbo.PaymentDetails
(
  PaymentID INT
);
GO

Şimdi tabloya, işleve ve eşanlamı referans alan bir görünüm oluşturun ve SELECTaşağıdakilere verin username:

CREATE VIEW dbo.SomeView
AS
  SELECT 
    p.PaymentID, 
    x = dbo.checkbar(), -- function that pulls from other DB
    y = (SELECT bar FROM dbo.foo) -- synonym to other DB
    FROM dbo.PaymentDetails AS p;
GO
GRANT SELECT ON dbo.SomeView TO username;
GO

Şimdi as komutunu çalıştırmayı deneyin usernameve görünümden yalnızca yerel sütunu seçin:

EXECUTE AS USER = 'username';
GO
  -- even though I don't reference any of the columns 
  -- in the other DB, I am denied SELECT on the view:
SELECT PaymentID FROM dbo.SomeView;
GO
REVERT;
GO

Sonuç:

Msg 916, Seviye 14, Durum 1, Satır 3
Sunucu asıl adı "kullanıcı adı", geçerli güvenlik bağlamı altında "ilgisiz_db" veritabanına erişemiyor.

Şimdi görünümü herhangi bir harici nesneye başvurmayacak şekilde değiştirin ve yukarıdakileri SELECTtekrar çalıştırın ve çalışır:

ALTER VIEW dbo.SomeView
AS
  SELECT 
    p.PaymentID 
    --x = dbo.checkbar(),
    --y = (SELECT bar FROM dbo.foo)
    FROM dbo.PaymentDetails AS p;
GO

Bize Ödeme Ayrıntıları, Hesap Ayrıntıları ve MyView nesneleri için komut dosyaları göstermemek, belki de bu sorgunun herhangi bir sonuç döndürüp döndürmediğini bize bildirebilirsiniz. Katalog görünümü aracılığıyla çeşitli nesnelere referans bulabilirsiniz sys.sql_expression_dependencies, ancak bu görünüm mükemmel değildir - sırayla yenilenen tüm görünümlere (örneğin görünümlerin diğer görünümlere veya altta yatan şemaya başvurması durumunda) bağlı olduğuna inanıyorum doğru olmak.

DECLARE 
  @dbname   SYSNAME = N'unrelated_db',
  @viewname SYSNAME = N'dbo.SomeView';

SELECT DISTINCT 
    [This object] = 
    OBJECT_SCHEMA_NAME([referencing_id]) 
      + '.' + OBJECT_NAME([referencing_id]), 
    [references this object] = 
    OBJECT_SCHEMA_NAME([referenced_id]) 
      + '.' + OBJECT_NAME([referenced_id]), 
    [and touches this database] = referenced_database_name,
    [and is a(n)] = o.type_desc,
    [if synonym, it references] = s.base_object_name
FROM sys.sql_expression_dependencies AS d
LEFT OUTER JOIN sys.objects AS o
ON o.[object_id] = d.referenced_id
LEFT OUTER JOIN sys.synonyms AS s
ON d.referenced_id = s.[object_id]
AND s.base_object_name LIKE '%[' + @dbname + ']%'
WHERE OBJECT_ID(@viewname) IN (
        referenced_id, 
        referencing_id, 
        (SELECT referencing_id FROM sys.sql_expression_dependencies 
        WHERE referenced_database_name = @dbname)
) OR referenced_database_name = @dbname;

SQL Server sadece unrelated_dbeğlenmek için erişmeye çalışmakla kalmayacak ... Kullanmaya çalıştığınız görünümden bu veritabanına bir bağ olması gerekir. Maalesef, görünüm tanımını ve dokunduğu nesneler hakkında daha fazla ayrıntı göremediğimizde, yapabileceğimiz tek şey spekülasyon yapmaktır. Düşünebileceğim iki ana şey eş anlamlılar veya üç bölümlü adlar kullanan işlevlerdir, ancak gerçek komut dosyalarını görmek bize tahmin etmek yerine daha iyi bir fikir verecektir. :-)

Ayrıca kontrol etmek isteyebilirsiniz sys.dm_sql_referenced_entities, ancak bu işlev yukarıdaki örnekte yararlı hiçbir şey döndürmez.


6
create login YourTpvLogin with password = 'enter new password here'
go

use SomeDb
go

create user YourTpvUser for login YourTpvLogin
go

grant select on YourView to YourTpvUser
go

Aşağıdakileri yaparak bunu test edebilirsiniz:

execute as user = 'YourTpvUser'
go

select *
from YourView

revert
go

Görünüşe göre bu tekrar tekrar ayrıcalık tanımıyor. Kullanıcının "YourView" öğesinden seçim yapmasına izin verilir, ancak "YourView" diğer ilişkilere / veritabanlarına bağlıysa, başarısız olur: Sunucu sorumlusu "YourTpvUser" geçerli güvenlik bağlamı altında "OtherDb" veritabanına erişemiyor.
lilalinux
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.