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

SQL Server:come autorizzare gli schemi?

Temo che la tua descrizione o la tua concezione del concatenamento della proprietà non siano chiare, quindi vorrei iniziare con quello:

"Concatenamento della proprietà" si riferisce semplicemente al fatto che durante l'esecuzione di una stored procedure (o visualizzazione) su SQL Server, il batch attualmente in esecuzione acquisisce temporaneamente i diritti/autorizzazioni del proprietario di sProc (o del proprietario dello schema di sProc) durante l'esecuzione di quel codice SQL. Quindi, nel caso di uno sProc, l'utente non può utilizzare quei priv per fare qualcosa che il codice sProc non implementa per lui. Nota in particolare che non acquisisce mai l'Identità del Titolare, solo suoi diritti, temporaneamente (comunque, EXECUTE AS... fa ciò).

Quindi l'approccio tipico per sfruttarlo per la sicurezza è:

  1. Inserisci tutte le tabelle dati (e anche tutte le viste non di sicurezza) nel proprio schema, chiamiamolo [dati] (sebbene in genere venga utilizzato [dbo] perché è già presente ed è troppo privilegiato per lo schema dell'utente). Assicurati che nessun Utente, Schema o Proprietario esistente abbia accesso a questo schema [dati].

  2. Crea uno schema chiamato [exec] per tutti gli sProcs (e/o eventuali visualizzazioni di sicurezza). Assicurati che il proprietario di questo schema abbia accesso allo schema [data] (questo è facile se rendi dbo il proprietario di questo schema).

  3. Crea un nuovo ruolo db chiamato "Utenti" e assegnagli l'accesso EXECUTE allo schema [exec]. Ora aggiungi tutti gli utenti a questo ruolo. Assicurati che i tuoi utenti dispongano solo dei diritti Connect e non abbiano accesso a nessun altro schema, incluso [dbo].

Ora i tuoi utenti possono accedere ai dati solo eseguendo sProcs in [exec]. Non possono accedere ad altri dati o eseguire altri oggetti.

Non sono sicuro che questo risponda alla tua domanda (perché non ero sicuro di quale fosse esattamente la domanda), quindi sentiti libero di reindirizzarmi.

Per quanto riguarda la sicurezza a livello di riga, ecco come lo faccio sempre con lo schema di sicurezza sopra:

  1. Implemento sempre la sicurezza a livello di riga come una serie di viste che eseguono il mirroring di ogni tabella e confrontano l'identità dell'utente (di solito con Suser_Sname() o uno degli altri) con un elenco di sicurezza digitato da un codice di sicurezza nella riga stessa. Queste sono le Security-Views.

  2. Crea un nuovo schema chiamato [righe], dai al suo proprietario l'accesso allo schema [dati] e nient'altro. Inserisci tutte le Security-Views in questo schema.

  3. Revocare l'accesso del proprietario [exec] allo schema [data] e concedergli invece l'accesso ai dati allo schema [rows].

Fatto. Ora la sicurezza a livello di riga è stata implementata inserendola in modo trasparente tra sProcs e tabelle.

Infine, ecco un appalto archiviato che utilizzo per aiutarmi a ricordare quanto di questo materiale di sicurezza oscuro funziona e interagisce con se stesso (oops, versione corretta del codice ):

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:versione corretta del codice)