sql >> Database teknologi >  >> RDS >> Sqlserver

SQL Server:Hvordan tillader skemaer?

Jeg frygter, at enten din beskrivelse eller din opfattelse af Ownership Chaining er uklar, så lad mig starte med det:

"Ejerskabskæde" refererer simpelthen til det faktum, at når en lagret procedure (eller visning) udføres på SQL Server, erhverver den aktuelt eksekverende batch midlertidigt rettighederne/tilladelserne fra sProc'ens ejer (eller sProc's skema's ejer), mens den udfører denne SQL-kode. Så i tilfælde af en sProc kan brugeren ikke bruge disse privs til at gøre noget, som sProc-koden ikke implementerer for dem. Bemærk især, at den aldrig opnår identiteten af ejeren, kun dets rettigheder, midlertidigt (dog, UDFØR SOM... gør dette).

Så den typiske tilgang til at udnytte dette til sikkerhed er at:

  1. Sæt alle datatabellerne (og alle ikke-sikkerhedsvisninger også) ind i deres eget skema, lad os kalde det [data] (selvom [dbo] typisk bruges, fordi det allerede er der og for privilegeret til brugerens skema). Sørg for, at ingen eksisterende brugere, skemaer eller ejere har adgang til dette [data]-skema.

  2. Opret et skema kaldet [exec] for alle sProcs (og/eller muligvis sikkerhedsvisninger). Sørg for, at ejeren af ​​dette skema har adgang til [data]-skemaet (dette er nemt, hvis du gør dbo til ejeren af ​​dette skema).

  3. Opret en ny db-Role kaldet "Brugere" og giv den EXECUTE adgang til [exec]-skemaet. Tilføj nu alle brugere til denne rolle. Sørg for, at dine brugere kun har Connect-rettigheder og ikke har givet adgang til noget andet skema, inklusive [dbo].

Nu kan dine brugere kun få adgang til dataene ved at udføre sProcs i [exec]. De kan ikke få adgang til andre data eller udføre andre objekter.

Jeg er ikke sikker på, om dette besvarer dit spørgsmål (fordi jeg var usikker på, hvad spørgsmålet præcist var), så du er velkommen til at omdirigere mig.

Hvad angår sikkerhed på rækkeniveau, er det sådan, jeg altid gør med sikkerhedsskemaet ovenfor:

  1. Jeg implementerer altid sikkerhed på rækkeniveau som en serie af visninger, der spejler hver tabel og sammenligner brugerens identitet (normalt med Suser_Sname() eller en af ​​de andre) med en sikkerhedsliste, der er indtastet fra en sikkerhedskode i selve rækken. Disse er sikkerhedsvisningerne.

  2. Opret et nyt skema kaldet [rækker], giv dets ejer adgang til [data]-skemaet og intet andet. Indsæt alle sikkerhedsvisningerne i dette skema.

  3. Tilbagekald [exec]-ejerens adgang til [data]-skemaet og giv den i stedet dataadgang til [rows]-skemaet.

Færdig. Nu er sikkerhed på rækkeniveau implementeret ved at glide det gennemsigtigt mellem sProcs og tabellerne.

Endelig er her et lagret indkøb, som jeg bruger til at hjælpe mig med at huske, hvor meget af disse obskure sikkerhedsting, der virker og interagerer med sig selv (ups, rettet version af kode ):

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:rettet version af kode)



  1. Sådan fungerer REGEXP_REPLACE() i MariaDB

  2. Hvordan laver jeg en trigger for at opdatere en kolonne i en anden tabel?

  3. Hvordan laver man fuld ydre joinforbindelse for at kombinere to tabeller i mysql?

  4. Hvordan kan jeg aktivere MySQL langsom forespørgselslog på min server?