CodeGym /Corsi /SQL SELF /Controllo accesso a livello di riga: Row-Level Security (...

Controllo accesso a livello di riga: Row-Level Security (RLS)

SQL SELF
Livello 47, Lezione 3
Disponibile

Se i permessi a livello di ruolo e tabella sono come “il buttafuori all’ingresso”, Row-Level Security è tipo una guardia personale che controlla se un utente può entrare in ogni singola stanza dell’edificio.

RLS ti aiuta a fare in modo che l’utente possa lavorare solo con le righe della tabella che gli sono permesse. Per esempio:

  • In un e-commerce, il manager deve vedere solo i propri ordini.
  • In una piattaforma CRM, il dipendente vede solo i clienti del proprio team.
  • In un sistema bancario, il cliente deve avere accesso solo ai propri conti.

Come funziona RLS

Alla base di RLS c’è il concetto di policy di accesso. Le policy definiscono quali righe della tabella sono visibili per un ruolo o utente e quali sono disponibili per modifiche (INSERT, UPDATE, DELETE).

Di default RLS è disattivato per tutte le tabelle, e va attivato manualmente.

Attivare RLS per una tabella

Dai, creiamo una tabella orders dove vengono salvati gli ordini dell’e-commerce:

CREATE TABLE orders (
    order_id SERIAL PRIMARY KEY,
    user_id INT NOT NULL,
    product_name TEXT NOT NULL,
    price NUMERIC NOT NULL
);

Aggiungiamo qualche dato di test:

INSERT INTO orders (user_id, product_name, price)
VALUES
    (1, 'Smartphone', 500),
    (2, 'Notebook', 1000),
    (1, 'Cuffie', 100),
    (3, 'Tastiera', 50);

Ora attiviamo RLS per questa tabella:

ALTER TABLE orders ENABLE ROW LEVEL SECURITY;

Cosa abbiamo fatto? Abbiamo attivato il meccanismo RLS, ma le policy non sono ancora impostate. Finché non crei le policy, RLS in pratica non influisce sull’accesso alla tabella.

Creare una policy di accesso

Per aggiungere regole di gestione accesso, si usa il comando:

CREATE POLICY nome_policy
ON tabella
[FOR { SELECT | INSERT | UPDATE | DELETE }]
TO ruolo
USING (condizione_accesso)
WITH CHECK (condizione_controllo);
  • FOR: definisce per quali operazioni si applica la policy (SELECT, INSERT, UPDATE, DELETE). Se lo salti, la policy vale per tutte le operazioni.
  • TO: indica per quali ruoli la policy è attiva. Se non lo specifichi, vale per qualsiasi ruolo.
  • USING: imposta la condizione che deve essere vera perché le righe siano visibili all’utente.
  • WITH CHECK: definisce la condizione di controllo per le operazioni INSERT e UPDATE.

Esempio: accesso solo ai propri ordini

Creiamo una policy che permette agli utenti di vedere solo i propri ordini. Supponiamo che l’id dell’utente corrente coincida con user_id nella tabella:

CREATE POLICY user_can_view_own_orders
ON orders
FOR SELECT
USING (user_id = current_user::INT);

Cosa succede qui?

  • La policy si chiama user_can_view_own_orders.
  • Si applica all’operazione SELECT.
  • Solo le righe dove user_id coincide con l’id dell’utente corrente (current_user) sono visibili.

Quindi, se hai fatto login come utente con user_id = 1, vedrai solo i tuoi ordini.

Verifica del funzionamento di RLS

Creiamo due utenti: user1 e user2.

CREATE ROLE user1 LOGIN PASSWORD 'password1';
CREATE ROLE user2 LOGIN PASSWORD 'password2';

Diamo alle role l’accesso alla tabella:

GRANT SELECT ON orders TO user1, user2;

Ora cambiamo utente in user1 e proviamo a fare una query:

SELECT * FROM orders;

Risultato: vedrai solo le righe dove user_id = 1.

Policy per INSERT

Supponiamo di voler permettere agli utenti di aggiungere solo i propri ordini (cioè la riga con user_id deve coincidere con l’id dell’utente corrente).

Creiamo una policy su INSERT:

CREATE POLICY user_can_insert_own_orders
ON orders
FOR INSERT
WITH CHECK (user_id = current_user::INT);

Ora, se l’utente user1 prova ad aggiungere un ordine dove user_id non è 1, la query fallirà con errore.

Policy per UPDATE e DELETE

Allo stesso modo puoi creare policy per modificare e cancellare dati. Per esempio:

Per aggiornare i propri dati:

CREATE POLICY user_can_update_own_orders
ON orders
FOR UPDATE
USING (user_id = current_user::INT)
WITH CHECK (user_id = current_user::INT);

Per cancellare i propri dati:

CREATE POLICY user_can_delete_own_orders
ON orders
FOR DELETE
USING (user_id = current_user::INT);

Applicare più policy

Puoi creare più policy per la stessa tabella. Verranno applicate tutte insieme. Per esempio, se per un ruolo ci sono più regole, PostgreSQL le controllerà tutte (logica AND).

Verifica e debug di RLS

Per controllare quali policy sono impostate su una tabella, usa il comando:

\di+ nome_tabella

Se vuoi disattivare temporaneamente RLS (tipo per l’admin), esegui:

ALTER TABLE orders DISABLE ROW LEVEL SECURITY;

Il ruolo amministratore SUPERUSER di default non è limitato da RLS, quindi può vedere tutti i dati.

Errori tipici nella configurazione di RLS

Gli errori possono capitare se ti dimentichi di:

  • Attivare RLS con il comando ALTER TABLE ... ENABLE ROW LEVEL SECURITY.
  • Impostare le policy giuste per tutte le operazioni (SELECT, INSERT, UPDATE, DELETE).
  • Scrivere correttamente la condizione in USING e WITH CHECK. Per esempio, se non controlli user_id, puoi aprire per sbaglio l’accesso a tutte le righe.

Row-Level Security è uno degli strumenti di sicurezza più potenti in PostgreSQL. Ti permette di gestire l’accesso con precisione a livello di riga e automatizzare la gestione dei permessi, cosa fondamentale per applicazioni complesse con alte esigenze di protezione dei dati.

2
Compito
SQL SELF, livello 47, lezione 3
Bloccato
Politiche complesse: accesso in lettura e modifica
Politiche complesse: accesso in lettura e modifica
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION