fine-grained access control [message #1517387] |
Fri, 19 December 2014 08:10  |
Eclipse User |
|
|
|
Hi,
i am using fine-grained access control. This works nicely at the server side. When the user (Medewerker) executes the MedewerkerService.store method the permission is checked and the method is only allowed when he tries to save his own record.
@Override
public MedewerkerFormData store(MedewerkerFormData formData) throws ProcessingException {
if (!ACCESS.check(new MedewerkerBewerkenPermission(formData.getMedewerkerNr()))) {
throw new VetoException(TEXTS.get("AuthorizationFailed"));
}
But when I use the permission at the client side it does not work. The fields and button of the form are always disabled.
public class ModifyHandler extends AbstractFormHandler {
@Override
public void execLoad() throws ProcessingException {
IMedewerkerService service = SERVICES.getService(IMedewerkerService.class);
MedewerkerFormData formData = new MedewerkerFormData();
exportFormData(formData);
formData = service.load(formData);
importFormData(formData);
setEnabledPermission(new MedewerkerBewerkenPermission(formData.getMedewerkerNr()));
}
Any idea what is going wrong or can't I use fine grainde permissions at the client side?
Regards Bertin
public class MedewerkerBewerkenPermission extends BasicHierarchyPermission {
private static final long serialVersionUID = 0L;
public static final int LEVEL_PERSOONLIJK = AutorisatieNiveauPersoonlijkCode.ID.intValue();
public static final int LEVEL_VESTIGING = AutorisatieNiveauVestigingCode.ID.intValue();
public static final int LEVEL_RID = AutorisatieNiveauRidCode.ID.intValue();
private Long m_medewerkerNr; // medewerkerNr van ingelogde MPX medewerker
public MedewerkerBewerkenPermission(Long medewerkerNr) {
super("MedewerkerBewerkenPermission", LEVEL_UNDEFINED);
m_medewerkerNr = medewerkerNr;
}
...
...
|
|
|
|
|
|
Re: fine-grained access control [message #1541801 is a reply to message #1541624] |
Fri, 02 January 2015 03:25  |
Eclipse User |
|
|
|
Maybe I can help. Just as a point of clarification, from reading your description it sounds to me like you don't need to be using "fine-grained" access control, but rather standard hierarchical controls. Fine-grained is where you allow access per object, and then every time you check for access, you ask "Can this user read the object with this id?" (very fine-grained). With hierarchical you're just asking "Can the user read objects at this security level?".
In your example, the behaviour is correct I think. The user's access level is loaded on startup, and does not change, so the result of execCheckLevel can be cached (and doesn't need to be called again). You need to shift the level-checking mechanism to outside of the permission object.
I use hierarchical access control. In addition to the inherited levels LEVEL_UNDEFINED(-1), LEVEL_NONE(0) and LEVEL_ALL(100), I use LEVEL_OWN(10) and LEVEL_GLOBAL(20). In my database, each Unit object has a visibility setting which determines if only its owner (current user is object's creator and has LEVEL_OWN access level) can access it, or whether all users with the LEVEL_GLOBAL permission can access it. My permission code is thus:
import org.eclipse.scout.rt.shared.security.BasicHierarchyPermission;
public class ReadUnitPermission extends BasicHierarchyPermission {
/**
* Can read own entries.
*/
public static final int LEVEL_OWN = 10;
/**
* Can read global entries.
*/
public static final int LEVEL_GLOBAL = 20;
private static final long serialVersionUID = 0L;
public ReadUnitPermission() {
super("ReadUnit", LEVEL_OWN);
}
}
Note that you set the "required" permission level in the constructor. In my case above, the default required permission level is "LEVEL_OWN". What's also important is that the permission level ids increase in value, so in my example LEVEL_UNDEFINED(-1) < LEVEL_NONE(0) < LEVEL_OWN(10) < LEVEL_GLOBAL(20) < LEVEL_ALL(100). When I want to know if the user has the permission, I can write:
ACCESS.getLevel(new ReadUnitPermission()) >= LEVEL_OWN
If I want to show filter out 'hidden' objects in an outline, I use this SQL select:
DB.selectInto(""
+ "SELECT UNIT_NR, "
+ " NAME, "
+ " LAST_MODIFIED,"
+ " SHARE_LEVEL "
+ " FROM UNIT "
+ " WHERE UNIT_NR IN :unitNrs "
+ " AND ((:permissionLevel = 100) OR (:permissionLevel >= 20 AND SHARE_LEVEL = " + PublicCode.ID + ") OR (:permissionLevel >= 10 AND SHARE_LEVEL = (" + PrivateCode.ID + ") AND USER_NR = :userNr)) "
+ " INTO :{unit.unitNr}, "
+ " :{unit.name}, "
+ " :{unit.lastModified},"
+ " :{unit.shareLevel} "
, formData
, new NVPair("permissionLevel", ACCESS.getLevel(new ReadUnitPermission()))
);
Also note, if you look at the javadoc for AbstractSqlService.execCustomBindFunction() it hints that there is standard bind support for checking permission levels using statements like:
::level(ReadUnitPermission)
I haven't tested this myself, but it might work.
|
|
|
Powered by
FUDForum. Page generated in 0.04268 seconds