Versio

Recordspecifieke rechten

Overzicht Reageren

Herjan -

Herjan -

15/01/2009 15:11:00
Quote Anchor link
Ik ben bezig aan een CMS waarin meerdere websites op dezelfde database en dezelfde serie bestanden draaien. De teksten, gebruikers e.d. van verschillende websites komen dus allemaal in dezelfde tabellen te staan op de server.

Nu loop ik tegen het probleem aan dat de websitebeheerders, als zij inloggen op de database, alle records van die tabellen kunnen lezen. Ze kunnen dus ook de teksten op andere websites zien (ook als die op de website zelf achter een inlogsysteem zitten). Dat is uiteraard niet de bedoeling.

Om dat te voorkomen vatte ik het wilde plan op om records aan databasegebruikers te koppelen, dus dat je een bepaalde gebruiker de eigendomsrechten van een bepaalde rij uit een tabel geeft. Elke websitebeheerder heeft FTP-toegang tot een index.php op zijn website, die eigenlijk niks meer doet dan het CMS includen. In dat bestandje kan ik ook databasegegevens opslaan, zodat elke website een eigen account heeft op de databaseserver. Maar de beheerders kunnen dus ook phpMyAdmin uploaden naar hun FTP-server en vervolgens met de gebruikersgegevens direct inloggen op de database om alle records te lezen én te wijzigen.

Alleen is er volgens mij geen doorsnee database engine die gebruikersrechten per record ondersteunt. Ik heb even gekeken naar pgSQL (die voor zover ik weet qua rechten etc. de meeste mogelijkheden biedt), maar die kan het niet.

Weet iemand toevallig hoe ik zoiets zou kunnen realiseren? Ik zou natuurlijk per website een database aan kunnen maken, maar omdat het systeem steeds geüpdate wordt als het al in gebruik is, betekent dat dat ik bij elke update alle databases langs moet lopen om wijzigingen in de structuur aan te brengen. Vandaar dat ik die optie voor het laatst bewaar.

Edit:
Even iets duidelijker geprobeerd te omschrijven.
Gewijzigd op 01/01/1970 01:00:00 door Herjan -
 
PHP hulp

PHP hulp

25/05/2012 14:15:56
Gesponsorde koppelingen:
BHosted Hosting al vanaf € 1,- per maand

Controleer nu gratis jouw domeinnaam:

  
 
Frank -

Frank -

15/01/2009 15:58:00
Quote Anchor link
Je bent dan verplicht om stored procedures te gebruiken en per gebruiker een eigen account te maken. In pgSQL werkt dat perfect, is volledig waterdicht.

Met views en rules kan het ook, maar rules vind ik nogal ***beep*** werken, vandaar dat mijn voorkeur uitgaat naar het gebruik van sp's.

Ik ken trouwens geen enkele database waarbij je op recordniveau rechten kunt uitdelen.
 
Herjan -

Herjan -

15/01/2009 16:32:00
Quote Anchor link
pgFrank schreef op 15.01.2009 15:58:
Je bent dan verplicht om stored procedures te gebruiken en per gebruiker een eigen account te maken.

Kun je iets meer uitleggen hoe ik dit kan gebruiken?
 
Frank -

Frank -

15/01/2009 17:23:00
Quote Anchor link
Ik zal eens een voorbeeldje inelkaar draaien.

Edit:

Aanmaken tabelletje waar de data in komt:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
CREATE TABLE berichten
(
  id serial NOT NULL,
  eigenaar text DEFAULT session_user,
  bericht text NOT NULL,
  CONSTRAINT berichten_pkey PRIMARY KEY (id)
)
WITH (OIDS=FALSE);
ALTER TABLE berichten OWNER TO postgres;
GRANT ALL ON TABLE berichten TO postgres;

De user "postgres" is superuser en mag er als enige bijkomen.

Dan de functie om data in deze tabel weg te schrijven:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
CREATE OR REPLACE FUNCTION add_bericht("content" text)
  RETURNS boolean AS
$BODY$
BEGIN
    INSERT INTO berichten (eigenaar, bericht) VALUES(session_user, content);

    RETURN true;
END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE SECURITY DEFINER
  COST 100;
ALTER FUNCTION add_bericht(text) OWNER TO postgres;

En het instellen van de rechten voor zowel public (iedereen) als postgres:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
GRANT EXECUTE ON FUNCTION add_bericht(text) TO public;
GRANT EXECUTE ON FUNCTION add_bericht(text) TO postgres;


En de functie om de data op te halen:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
CREATE OR REPLACE FUNCTION get_berichten(OUT "content" text)
  RETURNS SETOF text AS
$BODY$
DECLARE
    query    text;
    row        record;
BEGIN
    query := 'SELECT bericht FROM berichten WHERE eigenaar = ''' || session_user || '''';

    FOR row IN EXECUTE query LOOP
        content := row.bericht;
        RETURN NEXT;
    END LOOP;
    
    RETURN;
END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE SECURITY DEFINER
  COST 100
  ROWS 1000;
ALTER FUNCTION get_berichten() OWNER TO postgres;

En de rechten:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
GRANT EXECUTE ON FUNCTION get_berichten() TO public;
GRANT EXECUTE ON FUNCTION get_berichten() TO postgres;

Vervolgens maak je nog even een paar extra rollen aan:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
CREATE ROLE frank LOGIN
  PASSWORD 'frank'
  NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE;
CREATE ROLE erik LOGIN
  PASSWORD 'erik'
  NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE;
CREATE ROLE hans LOGIN
  PASSWORD 'hans'
  NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE;

Zorg er voor dat IEDERE user een eigen account krijgt, dat is onmisbaar bij het herkennen van de user. Wanneer je niet weet wie er is ingelogd, weet je ook niet of je de juiste data te pakken hebt. Dat lijkt me logisch.

Dankzij de constante "session_user" wordt er bij ieder record de eigenaar opgeslagen en kan je later dus weer per eigenaar de gewenste data ophalen. Ga er eens mee stoeien, werkt prima.

Zorg er wel voor dat er niemand in de tabellen kan komen, controleer dus nog even of er geen public rechten zijn op de tabellen. Daarmee heb je ook direct het minpunt van pgSQL te pakken, er worden teveel public rechten uitgedeeld bij het aanmaken van objecten. Hopelijk gooien ze die onzin er nog eens uit.
Gewijzigd op 01/01/1970 01:00:00 door Frank -
 
Frank -

Frank -

15/01/2009 17:51:00
Quote Anchor link
Klaar!
 
Herjan -

Herjan -

16/01/2009 21:58:00
Quote Anchor link
Ok, klinkt veelbelovend! De boel wordt er zeker wel wat langzamer van? Nja, dat moet ik dan maar op de koop toe nemen ;-)

Bedankt in ieder geval, dit ga ik eens even goed bekijken!
 
Frank -

Frank -

17/01/2009 00:34:00
Quote Anchor link
Waarom zou het langzamer worden? Tuurlijk, je hebt een query met een where, maar dat is dan ook alles.

Mocht de query wat langzaam worden, ga dan met EXPLAIN eens kijken waarom dat zo is. Waarschijnlijk moet je een index zetten op de kolom "eigenaar", dat maakt zoeken op eigenaar een stuk sneller.

Succes!
 



Overzicht Reageren

Get Adobe Flash player