jsr339-experts@jax-rs-spec.java.net

[jsr339-experts] Re: Feature Proposal: Using _at_RolesAllowed for JAX-RS resources

From: Sergey Beryozkin <sberyozkin_at_talend.com>
Date: Wed, 14 Nov 2012 16:15:19 +0000

On 14/11/12 10:14, Sergey Beryozkin wrote:
> On 13/11/12 19:10, Markus KARG wrote:
>>>> No I do not proposing the spec to support anything special in the
>>>> client for anything special in the server, please carefully check
>>> what
>>>> I actually proposed. The client is dependent of pure http. The server
>>>> is producing pure http. The only relation to Java EE is on the server
>>> side.
>>>>
>>>> As the interface is defined by pure http means, certainly such a
>>>> client will run rather perfectly with PHP server. I do not bind the
>>>> client to anything server specific. Nothing broken.
>>>>
>>>
>>> OK, lets talk practical.
>>>
>>> here is my resource:
>>>
>>> @Path("/")
>>> public class Resource {
>>> @GET
>>> @Path("/a")
>>> @RolesAllowed("AdminA")
>>> public Response getA() {}
>>>
>>> @POST
>>> @Path("/a")
>>> @RolesAllowed("AdminA")
>>> public Response postA() {}
>>>
>>> @POST
>>> @Path("/b")
>>> @RolesAllowed("AdminB")
>>> public Response postB() {}
>>> }
>>>
>>> The (UI) client logs in, and it's allocated 'AdminA' role. The UI can
>>> access '/a' and '/b'.
>>>
>>> Here are my questions:
>>>
>>> At what point do you expect to ping the runtime with OPTIONS ?
>>
>> This certainly is up to the client programmer as I did not propose
>> automatic
>> OPTIONS invocations.
>>
>> If I would be the client programmer, I would request OPTIONS once for
>> /a and
>> /b as soon as an operation-type widget (menu item, button, hyperlink,
>> etc.)
>> acting upon the particular URL needs to know its "enabled" state for the
>> first time, so it is "greyed out" right at the first impression.
>> Typically
>> this would be inside of something like "init()" of the GUI code.
>>
>>> Why it will be cheaper (and also less expensive for the server) than
>>> attempting to access '/b' and disable the button allowing the user to
>>> access "/b" upon the authorization failure ?
>>
>> Whether it is cheaper or not clearly depends on the particular
>> implementations of OPTIONS in comparison to "normal" methods like GET and
>> POST: If you follow my proposal, OPTIONS will not throw an access denied
>> exception, while a failed access attempt must do so, which in turn
>> obviously
>> results in a larger stack of operations to be performed (like exception
>> handler matching and so on). As a result the effectively executed code
>> will
>> be larger than checking OPTIONS first to defensively prevent exceptions.
>>
>
> Yes, I see why doing OPTIONS per every resource URI 'wired' to a
> specific action item and such can also work. Which approach is better
> JAX-RS 2.0 has to do with it.
>
> One of your thoughts was that it will let the client to avoid doing the
> extra calls in cases where the action is not actually allowed, but all
> you do is instead introduce *another round-trip with OPTIONS instead*,
> which will require JAX-RS (EJB) module do the job it is not supposed to
> do, aka, start checking '_at_RolesAllowed' as opposed to the security
> module doing it.
>
> Also, recall my note about PHP server. You'd expect the client
> experience be consistent and but it is likely the PHP server will be
> more modular and won't be able to get RBAC rules checked while
> processing OPTIONS.
>
>> But independent of any potential performance gain, cecking OPTIONS first
>> will always work with any methods, even with non-idempotent one. Your
>> idea
>> of simply "trying it out" to adjust the GUI will fail at least for the
>> DELETE method as it would obviously delete information just to find out
>> whether it potentially could delete them... but the GUI just wants to
>> know
>> whether the user MAY press the DELETE button, but it doesn't want to
>> actually DELETE anything just because the GUI is initialized.
>>
>
> As I said, this is the problem of monolitic UI frontends. I'd consider
> also another option, the user logs in, and gets the view formated on the
> server according to its RBAC provileges
>
>>> Do you expect POST be listed in Allowed ?
>>
>> "OPTIONS /" will never contain POST as there is no @POST method
>> defined for
>> "/".
>>
>> "OPTIONS /a" invoked for "AdminA" WILL contain POST in Allowed, but
>> NOT when
>> invoked for "AdminB" or others as your source defines that on "postA()".
>>
>> "OPTIONS /b" invoked for "AdminA" or others will NOT contain POST in
>> Allowed, but WILL for "AdminB" as your source defines that on "postB()".
>>
>>> How will you know that "/b" can not be accessed ?
>>
>> By requesting "OPTIONS /b" as "AdminA", as it does not return "POST" in
>> Allowed.
>>
> Sure this works - I do not agree it is a JAX-RS spec level issue
>
>> Okay now I may ask you a question:
>>
>> @DELETE
>> @Path("/a")
>> @RolesAllowed("AdminA")
>> public Response deleteA() {}
>>
>> How will your client know that "AdminA" is are allowed to invoke
>> deleteA()?
>> Using my proposal, the client learns this by requesting "OPTIONS /a" with
>> user "AdminA", which returns "DELETE" in Allowed. Using your idea in
>> contrast, you will never know, as in your first DELETE invocation the
>> data
>> is deleted (what the user possibly did not want to), but when then
>> user then
>> wants to DELETE actually, there is no more data to physically remove,
>> so you
>> will get back a an error code. You GUI produces two problems. Mine none.
>>
Was just checking the above - it does not make sense at all:

"Using your idea in contrast, you will never know, as in your first
DELETE invocation the data is deleted (what the user possibly did not
want to)".

If the user is in role then the delete will be allowed, if not - 403
will be returned. Yes, I can see how with OPTIONS you can do it the
other way around, but it's not a JAX-RS level issue. Just add a
pre-match filter operating an OPTIONS and do the analysis of
RolesAllowed and get your list of allowed methods...

Sergey

> Please see above about the per-user role-specific view. I guess there
> are few more options possible
>
> Sergey
>
>> Regards
>> Markus
>>
>>
>
>