webForumDet fria alternativet

Uppbyggnad av rättighetssystem

6 svar · 1 020 visningar · startad av Peeer

PeeerMedlem sedan mars 20025 907 inlägg
#1

Håller på med ett större projekt tillsammans med en hög kompisar, och skulle behöva lite tips på hur man bäst bygger upp ett välfungerande rättighetssystem. Tanken är att vem som helst ska kunna registrera sig som medlem och då få vissa "grundrättigheter". Sen ska administratören kunna ge denna användare ytterligare rättigheter (eller ta bort rättigheter för den delen).

På databasnivå har vi tänkt ut något sådanthär:

tblusers:
*ID - Användarens IDnummer
*nick - Nickname
*pass - password
....
*usergroup - Anger vilket gruppID användaren tillhör

tblgroups:
*groupID - Gruppens IDnummer
*name - Namn på gruppen, ex. members, guests, superadmin osv.
*description - Kort beskrivning av gruppen 

tblprivs:
*groupID - GruppID
*grouppriv - Ett nummer för varje rättighet gruppen har (mao. flera poster för varje grupp)

När man registrerar sig som användare är det meningen att man ska placeras i gruppen members och då få de rättigheter som den gruppen har. När man sedan ska få mer/mindre rättigheter så får administratören lägga användaren i en annan grupp (ev. en ny grupp).

Är detta ett bra sätt att bygga upp systemet på (tänker då främst på databastabellerna mm)? Hur kan man göra det bättre?

sgtpepperMedlem sedan apr. 20007 588 inlägg
#2

Det kan vara bra att även kunna sätta specifika rättigheter för en enskild användare, alltså inte enbart baserat på grupptillhörighet.

Det är även bra om en användare kan ingå i flera grupper, kanske vill man ha en admin-grupp per delsystem, men även ha ett gäng personer som är admin för flera av dessa delsystem. Dessa kan då vara medlemmar i två eller flera av delsystems-admin-grupperna.

Fördelen då är att man t.ex kan ge användaren foo extra rättigheter för vissa objekt trots att han ingår i en grupp som inte normalt har dessa rättigheter (t.ex tilldela en vanlig användare någon slags admin-rättighet i ett delsystem).

Jag skulle bygga upp det ungefär så här:

[b]user[/b]
 - [i]userID* [/i]
 - name
 - password

[b]group[/b]
 - [i]groupID*[/i]
 - name

[b]membership[/b]
 - [i]userID*[/i]
 - groupID

[b]objects[/b]
 - [i]objID*[/i]
 - name

[b]acl[/b]
 - userID
 - groupID
 - objID
 - access

membership
relationstabell för användarnas medlemskap i grupper

objects
identifierare för de olika komponenter/objekt i systemet som skall ha begränsningar beroende på rättighet

acl
access control list, relationstabell som vilken användare/grupp som har vilken rättighet för vilket objekt. Rättighetskolumnen access kan antingen vara ett bitmönster typ chmod, eller en nyckel till ytterligare en tabell med rättighetstyper.

Låt säga att systemet har en komponent "USERS", som används för att lista/uppdatera/lägga till användare osv i medlemsdatabasen och att systemet i fråga har fyra nivåer på rättigheterna, read, create, update och delete där rättigheterna identifieras av ett bitmönster av typen delete-update-create-read. 1111 är fulla rättigheter, 0001 är endast read-rättigheter, 0011 endast read och create osv.

Om någon vill använda komponenten "USERS" för att lista användare, så krävs read-rättighet, vill man skapa en ny användare så krävs create-rättigheter o.s.v. (Vilka rättigheter som krävs för att göra vad får man styra i komponentens programlogik).

För att söka fram vilken rättighet en viss användare har på ett visst objekt så använder man användarens id, följande sökning plockar fram den högsta rättigheten användaren har i acl-tabellen baserat på hans användar-id och grupptillhörighet:

SELECT sum(access)
FROM acl
WHERE (userID=? OR groupID in (SELECT groupID FROM membership WHERE userID=?)) AND objID=?;

Den rättighet som är "högst" kommer att returneras, oavsett om det är satt på en av användarens grupper eller individuellt på just denna användare.

Om användaren t.ex ingår i två grupper, där den första har 1=0001=read på detta objekt, den andra har 6=0110=create och update så ger SQL-satsen ovan summan av dessa två, dvs 6+1=7 vilket är 0111 binärt = read, create och update.

Alltså kan användaren få sina rättigheter från ett visst objekt utifrån medlemskap i n antal grupper samt även rättigheter satta på just hans konto.

När man har byggt upp datamodellen så kan man sedan skapa en gemensam logik för hela systemet som tar ett objekt samt en användare och returnerar användarens rättigheter för detta objekt.

Det här blev en hel uppsats och jag har säkert tänkt fel och/eller missat något någonstans :). Men tänk på att det är väldigt bra att kunna sätta rättigheter dels på grupp och dels på användare, samt att en användare bör kunna vara medlem i flera grupper.

PeeerMedlem sedan mars 20025 907 inlägg
#3

Underbart utförligt svar! :)
Ska ta upp det med de andra när vi träffas nästa gång, men det verkar mycket mer praktiskt än det vi kommit fram till. Stort tack!

sgtpepperMedlem sedan apr. 20007 588 inlägg
#4

Jag kom dock på en sak, jag tänkte lite fel när det gällde rättighetsflaggorna, om en användar har read 0001 (1) samt gruppen också har read 0001 (1) så blir ju summan 1+1=2=0010 = create, vilket är lite fel :). Man måste köra en boolsk OR på alla värden för att det skall bli rätt och det vet jag inte om/hur man kan göra i SQL. Kanske är det inte optimalt att ha rättigheterna som bitmönster.

Så själva hanteringen av rättigheter får ni nog fila lite på :)

PeeerMedlem sedan mars 20025 907 inlägg
#5

Mjo, upptäckte det själv nyss. Får fundera lite, men det löser sig nog på ett eller annat sätt :)

AddeladdeMedlem sedan jan. 20013 406 inlägg
#6

Hur gjorde ni?

PeeerMedlem sedan mars 20025 907 inlägg
#7

citera mig själv från ett par PM

Jag gav upp det där med bitmönster och gjorde en fullösning istället. Tabellerna ser ut som de gör i sgtpeppers inlägg med den skillnaden att man i acl-tabellen får ett flertal poster istället för en för varje objektid. Varje objekt/modul har jag delat upp i olika accessid'n (ex. skriv i gästbok har accessid 1, läs i gästbok har accessid 2, radera i egen gästbok accessid 3, radera i andras gästböcker accessid 4 osv). Sen har jag helt enkelt en post i acl-tabellen för varje accessid man har. Så om medlemmarna i grupp 1 ska ha alla rättigheter för just den modulen så kommer de alltså att ha 4 st poster i acl-tabellen.

Det finns säkert bättre sätt att lösa det på, men det fungerar iaf :)

143 ms totalt · 3 externa anrop · v20260731065814-full.fb544a5a
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
139 ms — hämta tråd, inlägg och bilagor (db)