sql >> Databáze >  >> RDS >> PostgreSQL

Předávání ID uživatele spouštěčům PostgreSQL

Možnosti zahrnují:

  • Když otevřete připojení, CREATE TEMPORARY TABLE current_app_user(username text); INSERT INTO current_app_user(username) VALUES ('the_user'); . Poté ve spouštěči SELECT username FROM current_app_user získat aktuální uživatelské jméno, případně jako dílčí dotaz.

  • V postgresql.conf vytvořte záznam pro vlastní GUC, jako je my_app.username = 'unknown'; . Kdykoli vytvoříte připojení, spusťte SET my_app.username = 'the_user'; . Poté ve spouštěčích použijte current_setting('my_app.username') funkce k získání hodnoty. Ve skutečnosti zneužíváte stroje GUC k poskytování proměnných relace. Přečtěte si dokumentaci odpovídající verzi vašeho serveru, protože vlastní GUC se ve verzi 9.2 změnily .

  • Upravte svou aplikaci tak, aby měla databázové role pro každého uživatele aplikace. SET ROLE tomuto uživateli před provedením práce. To vám nejen umožňuje používat vestavěný current_user funkce podobná proměnné na SELECT current_user; , také vám umožňuje vynutit zabezpečení databáze . Viz tato otázka. Můžete se přihlásit přímo jako uživatel namísto použití SET ROLE , ale to má tendenci ztěžovat sdružování připojení.

V obou všech třech případech, kdy sdružujete připojení, musíte být opatrní, abyste DISCARD ALL; když obnovíte připojení k bazénu. (Ačkoli to není zdokumentováno, DISCARD ALL provede RESET ROLE ).

Běžné nastavení pro ukázky:

CREATE TABLE tg_demo(blah text);
INSERT INTO tg_demo(blah) VALUES ('spam'),('eggs');

-- Placeholder; will be replaced by demo functions
CREATE OR REPLACE FUNCTION get_app_user() RETURNS text AS $$
SELECT 'unknown';
$$ LANGUAGE sql;

CREATE OR REPLACE FUNCTION tg_demo_trigger() RETURNS trigger AS $$
BEGIN
    RAISE NOTICE 'Current user is: %',get_app_user();
    RETURN NULL;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER tg_demo_tg
AFTER INSERT OR UPDATE OR DELETE ON tg_demo 
FOR EACH ROW EXECUTE PROCEDURE tg_demo_trigger();

Použití GUC:

  • V CUSTOMIZED OPTIONS části postgresql.conf , přidejte řádek jako myapp.username = 'unknown_user' . Na verzích PostgreSQL starších než 9.2 musíte také nastavit custom_variable_classes = 'myapp' .
  • Restartujte PostgreSQL. Nyní budete moci SHOW myapp.username a získejte hodnotu unknown_user .

Nyní můžete použít SET myapp.username = 'the_user'; když navážete připojení, nebo alternativně SET LOCAL myapp.username = 'the_user'; po BEGIN Pokud chcete, aby byla transakce lokální, což je výhodné pro sdružená připojení.

get_app_user definice funkce:

CREATE OR REPLACE FUNCTION get_app_user() RETURNS text AS $$
    SELECT current_setting('myapp.username');
$$ LANGUAGE sql;

Ukázka pomocí SET LOCAL pro aktuální uživatelské jméno transakce:

regress=> BEGIN;
BEGIN
regress=> SET LOCAL myapp.username = 'test_user';
SET
regress=> INSERT INTO tg_demo(blah) VALUES ('42');
NOTICE:  Current user is: test_user
INSERT 0 1
regress=> COMMIT;
COMMIT
regress=> SHOW myapp.username;
 myapp.username 
----------------
 unknown_user
(1 row)

Pokud použijete SET místo SET LOCAL nastavení se při odevzdání/rollbacku nevrátí, takže je trvalé po celou dobu relace. Stále se resetuje pomocí DISCARD ALL :

regress=> SET myapp.username = 'test';
SET
regress=> SHOW myapp.username;
 myapp.username 
----------------
 test
(1 row)

regress=> DISCARD ALL;
DISCARD ALL
regress=> SHOW myapp.username;
 myapp.username 
----------------
 unknown_user
(1 row)

Pamatujte také, že nemůžete použít SET nebo SET LOCAL s parametry vazby na straně serveru. Pokud chcete použít parametry vazby ("připravené příkazy"), zvažte použití formuláře funkce set_config(...) . Viz funkce správy systému

Použití dočasné tabulky

Tento přístup vyžaduje použití spouštěče (nebo raději pomocné funkce volané spouštěčem), který se pokouší načíst hodnotu z dočasné tabulky, kterou by měla mít každá relace. Pokud dočasnou tabulku nelze najít, je poskytnuta výchozí hodnota. To bude pravděpodobně poněkud pomalé . Pečlivě testujte.

get_app_user() definice:

CREATE OR REPLACE FUNCTION get_app_user() RETURNS text AS $$
DECLARE
    cur_user text;
BEGIN
    BEGIN
        cur_user := (SELECT username FROM current_app_user);
    EXCEPTION WHEN undefined_table THEN
        cur_user := 'unknown_user';
    END;
    RETURN cur_user;
END;
$$ LANGUAGE plpgsql VOLATILE;

Demo:

regress=> CREATE TEMPORARY TABLE current_app_user(username text);
CREATE TABLE
regress=> INSERT INTO current_app_user(username) VALUES ('testuser');
INSERT 0 1
regress=> INSERT INTO tg_demo(blah) VALUES ('42');
NOTICE:  Current user is: testuser
INSERT 0 1
regress=> DISCARD ALL;
DISCARD ALL
regress=> INSERT INTO tg_demo(blah) VALUES ('42');
NOTICE:  Current user is: unknown_user
INSERT 0 1

Zabezpečené proměnné relace

Existuje také návrh přidat do PostgreSQL „proměnné zabezpečené relace“. Jsou to trochu jako proměnné balíčku. Od PostgreSQL 12 tato funkce nebyla zahrnuta, ale dávejte pozor a ozvěte se na seznamu hackerů, pokud to potřebujete.

Pokročilé:vaše vlastní rozšíření s oblastí sdílené paměti

Pro pokročilé použití můžete dokonce nechat své vlastní rozšíření C zaregistrovat oblast sdílené paměti a komunikovat mezi backendy pomocí volání funkcí C, které čtou/zapisují hodnoty v segmentu DSA. Podrobnosti najdete v příkladech programování PostgreSQL. Budete potřebovat znalosti jazyka C, čas a trpělivost.



  1. Načíst názvy sloupců a typy uložené procedury?

  2. Výpočet mediánu pomocí dynamického kurzoru

  3. Připojení ke 4D z Javy

  4. Připojení k Informix (IDS12 DB) v IRI Workbench