users@jax-rs-spec.java.net

[jax-rs-spec users] [jsr339-experts] Re: Feature Proposal: Using @RolesAllowed for JAX-RS resources

From: Markus KARG <markus_at_headcrashing.eu>
Date: Tue, 13 Nov 2012 20:10:47 +0100

> > 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.

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.

> 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.

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.

Regards
Markus