sql >> Database >  >> RDS >> Sqlserver

SQL Server:Hoe toestemming geven voor schema's?

Ik vrees dat uw beschrijving of uw opvatting van Ownership Chaining onduidelijk is, dus laat ik daarmee beginnen:

"Ownership Chaining" verwijst eenvoudigweg naar het feit dat bij het uitvoeren van een opgeslagen procedure (of weergave) op SQL Server, de batch die momenteel wordt uitgevoerd tijdelijk de rechten/machtigingen van de eigenaar van de sProc (of de eigenaar van het schema van de sProc) verwerft tijdens het uitvoeren van die SQL-code. Dus in het geval van een sProc kan de gebruiker die priv's niet gebruiken om iets te doen dat de sProc-code niet voor hen implementeert. Merk vooral op dat het nooit de Identiteit . verwerft van de Eigenaar, alleen zijn rechten, tijdelijk (UITVOEREN ALS... doet dit echter wel).

Dus de typische benadering om dit te gebruiken voor beveiliging is om:

  1. Zet alle gegevenstabellen (en ook alle niet-beveiligde weergaven) in hun eigen schema, laten we het [data] noemen (hoewel meestal [dbo] wordt gebruikt omdat het er al is en te bevoorrecht is voor het schema van de gebruiker). Zorg ervoor dat geen bestaande gebruikers, schema's of eigenaren toegang hebben tot dit [data]-schema.

  2. Maak een schema met de naam [exec] voor alle sProcs (en/of eventuele beveiligingsweergaven). Zorg ervoor dat de eigenaar van dit schema toegang heeft tot het [data]-schema (dit is gemakkelijk als u dbo de eigenaar van dit schema maakt).

  3. Maak een nieuwe db-rol met de naam "Gebruikers" en geef deze EXECUTE-toegang tot het [exec]-schema. Voeg nu alle gebruikers toe aan deze rol. Zorg ervoor dat uw gebruikers alleen Connect-rechten hebben en geen toegang hebben tot enig ander schema, inclusief [dbo].

Nu hebben uw gebruikers alleen toegang tot de gegevens door de sProcs in [exec] uit te voeren. Ze kunnen geen toegang krijgen tot andere gegevens of andere objecten uitvoeren.

Ik weet niet zeker of dit je vraag beantwoordt (omdat ik niet zeker wist wat de vraag precies was), dus stuur me gerust door.

Wat betreft beveiliging op rijniveau, hier is hoe ik het altijd doe met het bovenstaande beveiligingsschema:

  1. Ik implementeer altijd beveiliging op rijniveau als een reeks weergaven die elke tabel spiegelt en de identiteit van de gebruiker vergelijkt (meestal met Suser_Sname() of een van de andere) met een beveiligingslijst die is ingetoetst op basis van een beveiligingscode in de rij zelf. Dit zijn de beveiligingsweergaven.

  2. Maak een nieuw schema met de naam [rijen], geef de eigenaar toegang tot het [data]-schema en niets anders. Zet alle beveiligingsweergaven in dit schema.

  3. Trek de [exec]-eigenaar de toegang tot het [data]-schema in en verleen hem in plaats daarvan gegevenstoegang tot het [rows]-schema.

Gedaan. Nu is beveiliging op rijniveau geïmplementeerd door deze transparant tussen de sProcs en de tabellen te schuiven.

Ten slotte is hier een opgeslagen procedure die ik gebruik om me te helpen herinneren hoeveel van deze obscure beveiligingsdingen werken en met zichzelf interageren (oeps, gecorrigeerde versie van code ):

CREATE proc [TestCnxOnly].[spShowProc_Security_NoEX]  as
--no "With Execute as Owner" for this version
--create User [UserNoLogin] without login
--Grant connect on database :: TestSecurity to Guest
--alter database TestSecurity set trustworthy on

--Show current user context:
select current_user as current_
, session_user as session
, user_name() as _name
, suser_name() as [suser (sproc)]
, suser_sname() as sname
, system_user as system_


--Execute As Login = 'UserNoLogin'
select current_user as current_
, session_user as session
, user_name() as _name
, suser_name() as [suser (after exec as)]
, suser_sname() as sname
, system_user as system_

EXEC('select current_user as current_
, session_user as session
, user_name() as _name
, suser_name() as [suser (in Exec(sql))]
, suser_sname() as sname
, system_user as system_')

EXEC sp_ExecuteSQL N'select current_user as current_
, session_user as session
, user_name() as _name
, suser_name() as [suser (in sp_Executesql)]
, suser_sname() as sname
, system_user as system_'

--Revert
select current_user as current_
, session_user as session
, user_name() as _name
, suser_name() as [suser (aftr revert)]
, suser_sname() as sname
, system_user as system_

[EDIT:gecorrigeerde versie van code)



  1. Sqlite Kolom toevoegen aan tabel op een bepaalde positie (Android)

  2. Hoe kan ik alle informatie over een tabel in Oracle krijgen?

  3. Onderstrepingstekens of camelCase in PostgreSQL-ID's, wanneer de programmeertaal camelCase gebruikt?

  4. Voorwaardelijke ORDER BY afhankelijk van kolomwaarden