web-dev-qa-db-ja.com

さまざまなSQL Serverスキーマのユーザー権限を設定する

特定のユーザーへのアクセスを制限する必要がありますが、dboが所有するテーブルのデータを表示できる必要があります。

私は次のことをしようとしています:

  1. dboスキーマは通常どおり機能し、すべてにアクセスできます
  2. schema1スキーマはschema1オブジェクトのみにアクセスできます
  3. schema1ビューまたはストアドプロシージャがdboが所有するテーブルのデータにアクセスする場合、権限チェーンは適切に
  4. user1はschema1へのアクセス権のみを持ち、他には何もありません。 #3の場合を除いて

これが私が試したものです:

  1. ランダムなパスワードでテストログインにマップされたuser1ユーザーを作成する
  2. いくつかのテストデータを含むdboスキーマにいくつかのテーブルを作成しました
  3. Schema1スキーマを作成しました
  4. Dbo.people、dbo.taglinks、およびdbo.tagsのデータにアクセスするschema1.profilesというビューから選択するschema1.get_profilesを作成しました

ただし、user1としてログインしているときに次のステートメントを使用します。

EXEC get_profiles 1

結果は:

The SELECT permission was denied on the object 'tags', database 'schema_test', schema 'dbo'.

私が試してみました WITH EXECUTE AS OWNERそして、「所有権の連鎖」がどのように機能することになっているのか理解できなくなっています。

私も試しました

GRANT EXECUTE ON SCHEMA::schema1 TO user1
GRANT INSERT ON SCHEMA::schema1 TO user1
GRANT SELECT ON SCHEMA::schema1 TO user1
GRANT UPDATE ON SCHEMA::schema1 TO user1
GRANT VIEW DEFINITION ON SCHEMA::schema1 TO user1

しかし、次のエラーが発生します(dboレベルのアクセス権を持つユーザーであるにもかかわらず)。

Cannot grant, deny, or revoke permissions to sa, dbo, entity owner, information_schema, sys, or yourself.

私が必要とするのは、私が与えるストアドプロシージャを介してデータにアクセスできるようにするためのuser1だけです。

また、これは最終的には既存のSQL Azureデータベースで動作することを目的としていますが、最初にローカルのダミーデータベースに対してテストしています。

16
Julia McGuigan

基本的な概念は GRANT/DENYスキーマ権限 を使用することです。ロールを作成してメンバーを追加することで、権限を効率的に管理できます。

以下はあなたを詳細に説明する例です

use master
go
--Create Logins
CREATE LOGIN UserA WITH Password='UserA123';
go
CREATE LOGIN UserB WITH Password='UserB123';

use AdventureWorks2008R2
go
--Create Database Users
CREATE USER UserA;
go
CREATE USER UserB;
go
--Create the Test Schemas
CREATE SCHEMA SchemaA AUTHORIZATION UserA
go
CREATE SCHEMA SchemaB AUTHORIZATION UserB
go

-- create test tables
create table schemaA.TableA (fname char(5))
go
insert into schemaA.TableA (fname) values ('Kin-A')
go

create table SchemaB.TableB (fname char(5))
go
insert into SchemaB.TableB (fname) values ('Kin-B')
go

今テストしてください:

--Test for UserA in SchemaA
EXEC('select * from schemaA.TableA') AS USER = 'UserA'
go
--Kin-A

-- Test for UserB in SchemaB == this should fail
EXEC('select * from SchemaB.TableB') AS USER = 'UserA'
go
--Msg 229, Level 14, State 5, Line 1
--The SELECT permission was denied on the object 'TableB', database 'AdventureWorks2008R2', schema 'SchemaB'.

次に、ストアドプロシージャを作成します。

CREATE PROCEDURE SchemaB.proc_SelectUserB
AS
    select * from schemaA.TableA;
go
create procedure schemaA.proc_SchemaA
as 
    select * from schemaA.TableA

次に、schemaBのSPのUserAに実行権限を付与します。

GRANT EXECUTE ON OBJECT::[SchemaB].[proc_SelectUserB] TO [UserA] 
go

テストして.. UserAがschemaBからSPを実行できるかどうかを確認します。これによりPASSになります。

EXECUTE AS LOGIN='UserA';
    Exec SchemaB.proc_SelectUserB;
    revert;
go
--- Kin-A

しかし、UserAはSchemaBからのデータを見ることができません。

EXECUTE AS LOGIN='UserA';
    select * from SchemaB.TableB
revert;
go

--- Msg 229, Level 14, State 5, Line 3
--- The SELECT permission was denied on the object 'TableB', database 'AdventureWorks2008R2', schema 'SchemaB'.

または、データベースロールを使用してユーザーを追加するだけで、アクセス許可の管理性を向上させることができます

EXEC sp_addrole 'SchemaBUsesSchemaAProc'
go
EXEC sp_addrolemember 'SchemaBUsesSchemaAProc','UserA';
go

以下のステートメントは、UserAがschemaAではなくschemaBを参照できることを確認します。良い点は、ユーザーをSchemaBUsesSchemaAProcロールに追加するだけで、そのロールに付与されているすべての権限を継承することです。

GRANT SELECT ON SCHEMA::SchemaA TO SchemaBUsesSchemaAProc;
go

UserAにSchemaBが所有するSPの実行のみを許可する場合は、以下のステートメントで処理を実行できます。

GRANT EXECUTE ON OBJECT::[SchemaB].[proc_SelectUserB] TO [SchemaBUsesSchemaAProc] 
go

このように、UserAはSchemaBのテーブルを表示できませんが、SchemaBからprocを実行できます。

以下は 許可階層 について説明します:

enter image description here

17
Kin Shah