Caution
Amennyiben a rendszerben használt felhasználói, illetve csoport azonosítók nem karakteresek, akkor azokat a View-ban konvertálni kell.
Ez a fejezet a RecroGrid Framework jogosultsági modulját, a RecroSec használatát mutatja be.
This topic contains the following sections:
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.
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
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.
AdministratorRoleName 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.
"RecroSec": {
"Enabled": true, //If it is true, every object must be parameterized; otherwise, parameters can be configured in the entity's RGO_RecroSec
"SingleUserMode": true,
"AdministratorRoleName": "RGF.Administrators",
"AnonymousId": "Anonymous",
//"RoleScope": "test",
"CacheMode": "Process" //Process, RGCache, Disable
},
//
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.
Ha értéke false, akkor nem figyeli a jogosultságot.
Egyéb esetben a meghatározott logikai objektumhoz kapcsolt jogosultságot figyeli.
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.
//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.
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)
{
//Gets permissions based on the parameter with objectPermissionId=2
return RecroSec.GetPermissionsForUser(RecroGridContext.GetCurrentUserId(), objectName, objectKey, dataRec, 2);
//Granting direct permissions based on the current user
//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)
{
//Gets permissions based on the parameter with objectPermissionId=2
return RecroSec.GetPermissionsForUser(RecroGridContext.GetCurrentUserId(), objectName, objectKey, dataRec, 2);
//Granting direct permissions based on the current user
//if (RecroSec.CurrentUserId == ...)
{
//return new UserPermissions("");
}
}
}
}
return base.GetPermissions(objectName, objectKey, dataRec, objectPermissionId);
}
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.
public partial class Products : IRecroSecPreprocessing, IRecroSecPostprocessing
{
//IRecroSecPreprocessing
public int? RecroSecPreprocessing(RecroSecProcessingParam arg)
{
if (arg.ObjectName.IndexOf("/") == -1 && Discontinued)
{
return 2;
}
return arg.ObjectPermissionId;
}
//IRecroSecPostprocessing
public void RecroSecPostprocessing(RecroSecProcessingParam arg, UserPermissions permissions)
{
if (arg.ObjectName.IndexOf("/") == -1 && Discontinued /*&& arg.UserId == ...*/)
{
//permissions.CRUD = "R";
}
}
}
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 = "";
}
}
}
}
}
A beállított jogosultságok az alkalmazás bármely pontján a RecroSec GetPermissionsForUser(String, 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)
{
RgfMenu menu = new();
menu.AddItem("Permission", "perm");
menu.AddItemGlobal("CustomPerm", "customperm");
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 "customperm":
var permission1 = RecroSec.GetPermissionsForUser(tracking.UserId, "RGProduct", null, dataRec);
messages.AddInfo(permission1.GetPermission("custom_perm") ? "has permission" : "does not have permission");
break;
}
return base.OnCustomFunctionAsync(tracking, dataRec, args, messages);
}
}