Définition des autorisations utilisateur pour différents schémas SQL Server

16

J'ai besoin de limiter l'accès à un utilisateur particulier, mais ils doivent toujours pouvoir voir les données dans les tables appartenant à dbo.

J'essaie de faire ce qui suit:

  1. le schéma dbo fonctionne normalement, a accès à tout
  2. le schéma schema1 n'a accès qu'aux objets schema1
  3. si une vue schema1 ou une procédure stockée accède aux données des tables appartenant à dbo, la chaîne d'autorisations est appropriée
  4. user1 a accès au schéma1, et rien d'autre; sauf dans le cas de # 3

Voici ce que j'ai essayé:

  1. Créer un utilisateur user1 mappé à une connexion de test avec un mot de passe aléatoire
  2. Création de quelques tables dans le schéma dbo avec des données de test
  3. Créé un schéma schema1
  4. Créé un schéma_get_profiles qui sélectionne dans une vue appelée schema1.profiles qui accède aux données dans dbo.people, dbo.taglinks et dbo.tags

Cependant, en utilisant l'instruction suivante lorsque vous êtes connecté en tant qu'utilisateur1:

EXEC get_profiles 1

résulte en:

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

J'ai essayé WITH EXECUTE AS OWNERet je ne peux pas commencer à comprendre comment le "chaînage de propriété" est censé fonctionner.

J'ai aussi essayé

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

mais j'obtiens l'erreur suivante (en dépit d'être un utilisateur avec un accès de niveau dbo):

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

Ce dont j'ai besoin, c'est user1 pour pouvoir accéder aux données via les procédures stockées que je leur donne, et rien d'autre.

En outre, cela est destiné à éventuellement vivre sur une base de données SQL Azure existante, mais je teste d'abord une base de données factice locale.

Julia McGuigan
la source
Reportez-vous à ma réponse: Comment masquer le schéma à l'utilisateur Faites-moi savoir si vous avez besoin de plus de précisions.
Kin Shah
1
Cela me semble plus clair. Je pense que le problème était que le propriétaire de Schema1 était défini sur User1, au lieu de dbo. J'ai configuré Schema1 pour qu'il appartienne à User1, je l'ai adapté et j'ai suivi la question, et j'ai pu faire fonctionner quelque chose. Vous pouvez proposer une réponse à la question si vous le souhaitez. Merci!
Julia McGuigan
Heureux que cela vous ait aidé.
Kin Shah

Réponses:

17

Le concept de base consiste à utiliser les autorisations de schéma GRANT / DENY . Vous pouvez gérer efficacement les autorisations en créant un rôle, puis en y ajoutant des membres.

Voici un exemple qui vous expliquera en détail

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

Maintenant testez:

--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'.

Créez maintenant des procédures stockées:

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

Accordez maintenant des autorisations d'exécution à UserA sur le SP de schemaB

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

Testez-le .. pour voir si UserA est capable d'exécuter SP à partir de schemaB. Cela passera

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

Mais UserA ne pourra pas voir les données de 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'.

Alternativement, vous pouvez utiliser DATABASE ROLE et simplement y ajouter des utilisateurs pour une meilleure gestion des autorisations:

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

L'instruction ci-dessous s'assurera que UserA est capable de voir schemaA et NOT schemaB. La bonne chose est que vous pouvez simplement ajouter des utilisateurs au SchemaBUsesSchemaAProcrôle et ils hériteront de toutes les autorisations accordées à ce rôle.

GRANT SELECT ON SCHEMA::SchemaA TO SchemaBUsesSchemaAProc;
go

Si vous souhaitez uniquement autoriser UserA à exécuter les SP appartenant à SchemaB, l'instruction ci-dessous fera le travail:

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

De cette façon, UserA n'est pas en mesure de voir les tables de SchemaB, mais peut toujours exécuter des proc à partir de SchemaB.

Ci-dessous expliquera la hiérarchie des autorisations :

entrez la description de l'image ici

Kin Shah
la source
2
Pour réitérer, il est important que les deux schémas appartiennent au même utilisateur. C'était le principal problème que j'avais.
Julia McGuigan