On Wed, Sep 9, 2015 at 7:56 PM, Mark <[email protected]> wrote:

> All users are coming from an LDAP server that I do not have the ability to
> modify.  Users will authenticate off of the LDAP server which will in turn
> provide the user's Subject instance.  Since I cannot modify the user's LDAP
> entry, how can I assign permissions to the user?  I can get the list of
> groups(roles) for the user and could use that to populate the
> GroupPermission object, but there's no access info in LDAP for the user so
> I don't know where/how to insert the access that a user needs to complete
> this task.
>

Groups are a detail specific to Portofino; it's just an example. You could
have a UserDatabasePermission object holding just the information you need
to check a user's permissions on a database object, say the user id.
The important point is that Permission is a class, and not just a string; a
class implementing logic ("does permission X imply permission Y?") that you
can subclass and write according to your application's rules.

To add the Permission to the Subject requires a little bit of code in the
Realm:

public AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection
principals) {
    ...
    SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(groups);
    ...
    Permission permission = new GroupPermission(groups);
    info.setObjectPermissions(Collections.singleton(permission));
    ...
}

so if you're using the stock LDAPRealm, you'll have to subclass it to add
your special permission object.


>
> On Wed, Sep 9, 2015 at 11:57 AM, Alessio Stalla <
> [email protected]> wrote:
>
>> On Wed, Sep 9, 2015 at 5:39 PM, Mark <[email protected]> wrote:
>>
>>> I am not interested in using annotations, so we don't need to worry
>>> about that.
>>>
>>> The part I don't understand here is, how can you assign permissions to a
>>> Subject dynamically?
>>>
>>
>> As far as I know, you can't. What you can do is to have your own, dynamic
>> subclass of Permission. Your users will have a fixed set of permissions -
>> they could be a single permissions object, or Read/Write or whatever,
>> depending on the granularity you want to achieve. Those will, however,
>> dynamically imply a variable set of permissions that reflect your data.
>>
>> An example will perhaps make it clearer. In Portofino[*], we have users
>> with groups (roles) and an application made of pages which can be
>> dynamically added, removed, moved around etc. Each page has its own
>> permission setup - for example, /home will be readable by anyone, while
>> /admin only by administrators, and /home/profile only by authenticated
>> users. Page permissions can be changed dynamically as well and can be
>> inherited from parent pages. So, computing permissions statically when the
>> user logs in is not possible.
>> Thus, each user is assigned a single Permission object which contains all
>> their groups.
>> http://sourceforge.net/p/portofino/mercurial/ci/default/tree/portofino-pageactions/src/main/java/com/manydesigns/portofino/shiro/GroupPermission.java
>> Each page, on the other hand, is associated to a PagePermission object.
>> http://sourceforge.net/p/portofino/mercurial/ci/default/tree/portofino-pageactions/src/main/java/com/manydesigns/portofino/shiro/PagePermission.java
>> That object holds the actual permissions for that page, computed for each
>> web request according to inheritance. The magic happens in
>> GroupPermission.implies, which is called against the user's permissions and
>> the page's declared permissions. So, in the end, user code only has to do
>>
>> PagePermission pagePermission = new PagePermission(...);
>> if(subject.isPermitted(pagePermission)) {
>>     ...
>> }
>>
>> Hope this helps.
>>
>> PS we do use annotations as well, because our data happens to be code
>> (for the pages' methods). However, that won't be your case.
>>
>> [*] our web application framework, http://portofino.manydesigns.com
>>
>>
>>> On Wed, Sep 9, 2015 at 11:12 AM, Tomas Lund Petersen <
>>> [email protected]> wrote:
>>>
>>>> Hi,
>>>> This is posible and I have done it.
>>>> But you can't use annotations. You have to manually check for the users
>>>> permisions using User.isPermited(requidedPermission);
>>>> For example:
>>>>       f(SecurityUtils.getSubject().isPermitted(requiiredPermission)){
>>>>         //do stuff here
>>>>      }else{
>>>>         throw new UnauthorizedException ();
>>>>      }
>>>> Where requiredPermission must be the permission asociated to access
>>>> record XYZ or QRS in your example. You will have to look it up Dinamically.
>>>> Hope it helps,
>>>> Tomas Lund Petersen
>>>>
>>>> On Wed, Sep 9, 2015 at 11:49 AM, Mark <[email protected]> wrote:
>>>>
>>>>> Thanks for the information.  Would it be possible to set a Subject's
>>>>> record access at runtime?  I'm envisioning the following scenario:
>>>>>
>>>>> User A, who is in Group 1 creates a record (XYZ) and only wants to
>>>>> have full access for themself.
>>>>> User B, who is also in Group 1 tries to access record XYZ.  User B
>>>>> should be denied.
>>>>>
>>>>> User C, who is in Group 1 creates a Record (QRS) wants everyone in
>>>>> their group to read the record.
>>>>> User D, who is in Group 1 wants to read record QRS.  User D should be
>>>>> able to read record QRS but not make changes.
>>>>>
>>>>> This feels like it should be similar to UNIX file permissions, but I
>>>>> don't know how to enforce all this at runtime in Shiro.  The first 
>>>>> scenario
>>>>> would make the record XYZ have permission of 600, while the permissions on
>>>>> record QRS would be 660.  Maybe I just need a custom class that can
>>>>> translate this in Shiro.  If so, would this require a custom
>>>>> PermissionResolver?
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> On Wed, Sep 9, 2015 at 2:48 AM, scSynergy <[email protected]>
>>>>> wrote:
>>>>>
>>>>>> You can verify whether a user / role has access to the record by
>>>>>> including
>>>>>> these lines at the very beginning of the method which retrieves it
>>>>>> from your
>>>>>> database:
>>>>>> Set<WildcardPermission> permissions = new HashSet<>();
>>>>>> permissions.add(new WildcardPermission("record:read:user"));
>>>>>> permissions.add(new WildcardPermission("record:write:user"));
>>>>>> SecurityUtils.getSubject().checkPermission(permissions);
>>>>>> // retrieve stuff from database
>>>>>>
>>>>>> The checkPermission method will continue on normally when the subject
>>>>>> has
>>>>>> the needed permissions and throw an UnauthorizedException if not.
>>>>>>
>>>>>> You can also use annotations like
>>>>>> @RequiresPermissions({"record:read:user",
>>>>>> "record:write:user"}) but then you cannot define the needed
>>>>>> permissions
>>>>>> dynamically because annotations require constant values - this is
>>>>>> *not* a
>>>>>> limitation of Shiro but of annotations.
>>>>>>
>>>>>> Have a look at the API to get an idea of what Shiro supports
>>>>>> https://shiro.apache.org/static/1.2.3/apidocs/ .
>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> View this message in context:
>>>>>> http://shiro-user.582556.n2.nabble.com/Dynamic-Authorization-tp7580696p7580697.html
>>>>>> Sent from the Shiro User mailing list archive at Nabble.com.
>>>>>>
>>>>>
>>>>>
>>>>
>>>
>>
>>
>> --
>> *Alessio Stalla* | Software Architect
>> M: +39 340 7824743 | T: +39 010 566441 | F: +39 010 8900455
>> [email protected] | www.manydesigns.com
>>
>> MANYDESIGNS s.r.l.
>> Via G. D'Annunzio, 2/51 | 16121 Genova (GE) | Italy
>>
>
>


-- 
*Alessio Stalla* | Software Architect
M: +39 340 7824743 | T: +39 010 566441 | F: +39 010 8900455
[email protected] | www.manydesigns.com

MANYDESIGNS s.r.l.
Via G. D'Annunzio, 2/51 | 16121 Genova (GE) | Italy

Reply via email to