Click or drag to resize

RecroSec

Ez a fejezet a RecroGrid Framework jogosultsági modulját, a RecroSec használatát mutatja be.

Áttekintés

Az alapszintű jogosultsági rendszert, ahol miden egyes RecroGrid hozzáférését globálisan lehet paraméterezni, a RecroSec nagyon jól kiegészíti, mivel többfelhasználós környezetben felhasználónként lehet szabályozni a jogosultságokat.

A RecroSec jogosultsági rendszer három darab adatbázis View-en keresztül képes kapcsolódni bármely típusú felhasználói nyilvántartáshoz. A rendszer a felhasználói nyilvántartást kizárólag olvasásra használja, és egy külön jogosultsági réteg bevezetésével kapcsolja a felhasználókhoz és csoportokhoz a jogosultságokat. A jogosultságokat futásidőben egy online felületen lehet paraméterezni. Az egyes felhasználók a különböző fizikai és logikai objektumokhoz tartozó jogosultsága, az erre kialakított függvénnyel az alkalmazás bármely pontján lekérdezhető, a RecroGrid használata esetén pedig automatikus a kiértékelés.

Adatok
Adminisztrátori felület
Folyamatábra

Inicializálás

Inicializálás, logikai felépítését, paraméterezés

Definiálni kell az adatbázisban három darab View-t, ami alapján a RecroSec képes felismerni a rendszerben használt felhasználókat és felhasználói csoportokat.

  • vRecroSec_User -> két karakteres mező: UserId és UserName

  • vRecroSec_Role -> három karakteres mező: RoleId, RoleName és RoleScope

  • vRecroSec_UsersInRole -> két karakteres mező: UserId és RoleId

Caution note Caution

Amennyiben a rendszerben használt felhasználói, illetve csoport azonosítók nem karakteresek, akkor azokat a View-ban konvertálni kell.

Note Note

ASP.NET Identity használata esetén ezek a View-k automatikusan létrejönnek.

Az alkalmazás appsettings.json beállításában az alkalmazásbeállítások alatt a RecroSec szekcióban engedélyezni kell a RecroSec használatát, ami minimálisan három beállítást igényel:

  • SingleUserMode beállítás legyen false.

  • AdministratorGroupName beállításban definiálni kell az Adminisztrátori csoportnak a névét.

  • Definiálni kell egy statikus függvényt, ami visszaadja a aktuális felhasználó azonosítóját, és ennek a függvénynek a elérést meg kell adni a CurrentUserIdProperty beállításban.

appsettings.json
"RecroSec": {
  "Enabled": true, //true eseten minden objektumot paraméterezni kell, egyébként az entitásban lehet jelezni, hogy RecroSec kell
  "SingleUserMode": true,
  "AdministratorGroupName": "Administrators",
  //"RoleScope":  "test",
  "CacheMode": "Process", //Process, RGCache, Disable
  "AnonymousId": "Anonymous"
},
Tip Tip

A beállításokat az alkalmazásban is lehet definiálni (lásd RecroSec properties), így biztosítva, hogy ne lehessen jogosultsági rendszert kikapcsolni.

RecroGrid kapcsolat, paraméterezés

Ha a RecroSec a appsettings.json beállításában engedélyezett, akkor alapértelmezés szerint minden RecroGrid az entitás nevéhez tartozó logikai objektum jogosultsági beállításait használja. Ha az nem definiált, vagy az entitás RGO_RecroSec opciós beállítás false, akkor az adminisztrátor kivételével senkinek nem lesz hozzá jogosultsága. Ha az RGO_RecroSec opciós beállítás értéke true, akkor a entitás neve, vagy egyéb esetben a meghatározott logikai objektum alapján keresi a jogosultságot, függetlenül a globális RecroSec engedélyezéstől.

Ha a fentiek alapján a jogosultság ellenőrzése engedélyezett, akkor a RecroGrid alapértelmezés szerint a List nézetben entitás (tábla), Form nézetben pedig rekord szinten figyeli a jogosultságot. Az RGO_RecroSecLevel opciós beállítás segítségével ez megváltoztatható:

  • Ha a beállítás tartalmazza a Row kulcsszót, akkor List nézetben is rekordonként figyeli a jogosultságot.

  • Ha a beállítás tartalmazza a Column kulcsszót, akkor List, és Form nézetben is oszloponként figyeli a jogosultságot.

További lehetőség, ha csak néhány oszlopra kell (vagy nem kell) figyelni a jogosultságot, akkor azt a mezőhöz definiált RGO_RecroSec opciós beállítással lehet megadni:

  • Ha értéke true, akkor entitáshoz kapcsolt RGO_RecroSec/Alias alapján figyeli a jogosultságot.

    Note Note

    RGO_RecroSec a fent leírtak szerint, Alias pedig a mező Alias azonosítója.

  • Ha értéke false, akkor nem figyeli a jogosultságot.

  • Egyéb esetben a meghatározott logikai objektumhoz kapcsolt jogosultságot figyeli.

    Tip Tip

    Ha ugyanazon feltétel alapján több mezőt is lehet figyelni, akkor ugyanahhoz a logikai objektumhoz több mezőt is hozzá lehet kapcsolni.

    A RGO_RecroSecCol opciós beállítással megadható, hogy az oszlop szintű jogosultság kötelező legyen. Ebben az esetben a nem definiált oszlopok jogosultsága read, akkor is ha a rekord jogosultsága write. Akkor hasznos, ha csak néhány mezőnek kell write jog.

Ha az RGO_RecroSecLevel opciós beállításban a rekord szintű jogosultság engedélyezve van, akkor List nézetben a rendszer már az SQL adatlekérdezésben hozzákapcsolja az aktuális entitáshoz a RecroSec-ben definiált logikai objektumokat a rekordok kulcsa alapján, hogy ne keljen ezt rekordonként egyesével megtenni. A lekérdezést optimalizálni lehet, ha az entitás mezői között (vagy akár már adatbázis szinten) szerepel az a mező, ahol az Alias ObjectPermissionId.

Adatfüggő ObjectPermissionId ajánlás
//ColName
ESQL:(case when {0}.discontinued=true then 2 else 1 end)
//Alias
ObjectPermissionId

Bonyolultabb esetben szükség lehet szerveroldalon befolyásolni a jogosultság kiértékelését, amit a GetPermissions(String, String, Object, NullableInt32) virtuális metódus megvalósításával lehet elvégezni.

Rekordszintű felülbírálás szerveroldalon
protected override UserPermissions GetPermissions(string objectName, string objectKey = null, object dataRec = null, int? objectPermissionId = null)
{
    if (objectName.IndexOf("/") == -1)
    {
        if (dataRec is Products && ((Products)dataRec).Discontinued)
        {
            //Jogosultság lekérése a paraméterezésből a objectPermissionId=2 szerint
            return RecroSec.GetPermissionsForUser(this.RecroGridContext.GetCurrentUserId(), objectName, objectKey, dataRec, 2);

            //Közvetlen jogosultság megadása aktuális felhasználó szerint
            //if (RecroSec.CurrentUserId == ...)
            {
                //return new UserPermissions("R");
            }
        }
        else if (dataRec is RGClientColumn[])
        {
            RGClientColumn[] clientRec = (RGClientColumn[])dataRec;
            var discontinued = clientRec.SingleOrDefault(r => r.Property.Alias.Equals("discontinued", StringComparison.InvariantCultureIgnoreCase));
            if (discontinued != null && ((bool)discontinued.DbValue))
            {
                //Jogosultság lekérése a paraméterezésből a objectPermissionId=2 szerint
                return RecroSec.GetPermissionsForUser(this.RecroGridContext.GetCurrentUserId(), objectName, objectKey, dataRec, 2);

                //Közvetlen jogosultság megadása aktuális felhasználó szerint
                //if (RecroSec.CurrentUserId == ...)
                {
                    //return new UserPermissions("");
                }
            }
        }
    }
    return base.GetPermissions(objectName, objectKey, dataRec, objectPermissionId);
}
Tip Tip

Szükség esetén az RG_Self Entity típusú mező definiálásával, List nézetben is (a megjelenítendő mezőktől függetlenül) beolvasásra kerül a teljes rekord.

Elő- és utófeldolgozás

Szerveroldali kódszintű paraméterezés, felülbírálás, egyedi típusú jogosultságok

A jogosultságok végső eredményét befolyásolni lehet egy elő- és egy utófeldolgozási lépésben.

Előfeldolgozás esetén módosítani lehet, hogy melyik logikai objektumhoz kapcsolt jogosultságot kell használni. A lehetőségek a következők:

  • Az aktuális típusos rekord IRecroSecPreprocessing interface alapján.

  • Logikai objektumhoz kapcsolódó Preprocessing metódus a paraméterezés alapján.

  • Logikai objektumhoz kapcsolódó PreprocessingTSQL SQL procedure a paraméterezés alapján.

Utófeldolgozás esetén az aktuális felhasználó végső jogosultságait lehet módosítani az aktuális objektumhoz. A lehetőségek a következők:

  • Az aktuális típusos rekord IRecroSecPostprocessing interface alapján.

  • Logikai objektumhoz kapcsolódó Postprocessing metódus a paraméterezés alapján

  • Logikai objektumhoz kapcsolódó PostprocessingTSQL SQL procedure a paraméterezés alapján.

Tip Tip

Ha kód szinten kell módosítani a jogosultságot, akkor javasolt inkább az előfeldolgozások választása (és esetleges új logikai objektumok létrehozása), mert akkor megmarad a felhasználónkénti online paraméterezhető lehetőség.

Elő- és utófeldolgozás interface
public partial class Products : IRecroSecPreprocessing, IRecroSecPostprocessing
{
    //IRecroSecPreprocessing
    public int? RecroSecPreprocessing(RecroSecProcessingParam arg)
    {
        if (arg.ObjectName.IndexOf("/") == -1 && this.Discontinued)
        {
            return 2;
        }
        return arg.ObjectPermissionId;
    }
    //IRecroSecPostprocessing
    public void RecroSecPostprocessing(RecroSecProcessingParam arg, UserPermissions permissions)
    {
        if (arg.ObjectName.IndexOf("/") == -1 && this.Discontinued /*&& arg.UserId == ...*/)
        {
            //permissions.CRUD = "R";
        }
    }
}
Elő- és utófeldolgozás statikus metódusok alapján
public partial class Products
{
    public static int Preprocessing(RecroSecProcessingParam arg)
    {
        object dataRec = arg.Target;
        if (arg.ObjectName.IndexOf("/") == -1)
        {
            if (dataRec is Products && ((Products)dataRec).Discontinued)
            {
                return 2;
            }
            if (dataRec is RecroGrid.RGClientColumn[])
            {
                var clientRec = (RecroGrid.RGClientColumn[])dataRec;
                var discontinued = clientRec.SingleOrDefault(r => r.Property.Alias.Equals("discontinued", StringComparison.InvariantCultureIgnoreCase));
                if (discontinued != null && ((bool)discontinued.DbValue)/*&& arg.UserId == ...*/)
                {
                    return 2;
                }
            }
        }
        return arg.ObjectPermissionId;
    }
    public static void Postprocessing(RecroSecProcessingParam arg, UserPermissions permissions)
    {
        object dataRec = arg.Target;
        if (arg.ObjectName.IndexOf("/") == -1)
        {
            if (dataRec is Products && ((Products)dataRec).Discontinued/*&& arg.UserId == ...*/)
            {
                //permissions.CRUD = "R";
            }
            if (dataRec is RecroGrid.RGClientColumn[])
            {
                var clientRec = (RecroGrid.RGClientColumn[])dataRec;
                var discontinued = clientRec.SingleOrDefault(r => r.Property.Alias.Equals("discontinued", StringComparison.InvariantCultureIgnoreCase));
                if (discontinued != null && ((bool)discontinued.DbValue)/*&& arg.UserId == ...*/)
                {
                    //permissions.CRUD = "";
                }
            }
        }
    }
}
Egyedi jogosultságok, lekérdezések

A beállított jogosultságok az alkalmazás bármely pontján a RecroSec GetPermissions(String, String, Object, NullableInt32) metódus segítségével egyszerűen lekérdezhetők.

public partial class RGProduct : RecroGridDBC<Products>
{
    public RGProduct(IRecroGridContext rgContext)
        : base(rgContext)
    {
        RGCustomMenu menu = new RGCustomMenu();
        menu.AddItem("Permission", "perm");
        menu.AddItemGlobal("Egyedi", "egyedi");
        this.RGOptions["RGO_CustomMenu"] = menu;
    }
    protected override Task<(bool Success, Products DataRec)> OnCustomFunctionAsync(RecroTrack tracking, Products dataRec, CustomFunctionEventArgs args, RGUIMessages messages)
    {
        if (dataRec != null)
        {
            switch (args.FunctionName)
            {
                case "perm":
                    var permission = RecroSec.GetPermissionsForUser(tracking.UserId, "RGProduct", null, dataRec);
                    messages.AddInfo(permission.CRUD);
                    break;
            }
        }
        switch (args.FunctionName)
        {
            case "egyedi":
                var permission1 = RecroSec.GetPermissionsForUser(tracking.UserId, "RGProduct", null, dataRec);
                messages.AddInfo(permission1.GetPermission("egyedi1") ? "van joga" : "nincs joga");
                break;
        }
        return base.OnCustomFunctionAsync(tracking, dataRec, args, messages);
    }
}
See Also

Other Resources