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: Tue, 20 Nov 2012 10:00:36 +0000

On 17/11/12 09:30, Markus KARG wrote:
>>> Nice idea to spare even more workload, but what you propose is an
>>> extension to http, while my proposal was 100% pure http. And I wonder
>>> why you want to invent a special method for that, as it is the core
>> intention of HTTPs'
>>> OPTIONS method to tell the client all the possible options ALLOWED
>> for
>>> a given URI. So I would understand if you simply add another
>>> well-known header like the "Depth: infinite" header of WebDAV to get
>>> the sub-URL answers you intend.
>>
>> OPTIONS /a
>> "Depth: infinite"
>>
>> works partially, isnt it ? The above will return a single "Allow", the
>> intersection of say Allow from "/a" itself, "/a/d" and "/a/c". And
>> getting OPTIONS sent per every URI to which UI has some dedicated area
>> for sucks.
>>
>> I think I will prototype something in CXF around X-options.
>>
>> Either way, I'm -1 on getting JAX-RS runtime to do the authorization-
>> based filtering of Allow. It is up to you and other experts to do the
>> rest
>
> I understand your concerns but before you really choose to not go with
> OPTIONS and start going with X-OPTIONS, I really ask you to read chapter
> "9.2 OPTIONS" http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html of RFC
> 2616 to see that mine and your extensions both are covered by the semantics
> it describes. That chapter says that you are allowed to extends OPTIONS for
> any extensions like the one you plan for X-OPTIONS, without losing the
> guarantee how OPTIONS will be processed (e. g. that it is definitively never
> cached, is safe, is dempotent, and so on). Particularly, if you understand
> why chapter "9.1.1 Safe Methods" and chapter "9.2 OPTIONS" directly follow
> up and both talk about the user's identity and the "Allow" header, will open
> your eyes that all we need and all you want is already in that RFC!
>
> For example, it is perfectly valid to send other headers with request and
> response, or to send a content-negotiated entity in the response. As The
> semantics of OPTIONS fit perfectly the "inspect for authorization" scenario,
> I want to ask you to do it this way instead as it includes your solution and
> does not do additional harm. Please go with OPTIONS but do not invent
> X-OPTIONS:
>
> * Pure http Style: For *authenticated* OPTIONS requests, please remove all
> methods from "Allow" response header that in fact are forbidden due to
> @RolesAllowed. This fits 100% pure http as defined by this RFC, does not
> harm anybody or any scenario, and is useful for everybody as the "Allow"
> header does not tell lies anymore (compared to a non-authenticated OPTIONS
> request), as it does not anymore contain methods that actually *not* allowed
> (the authenticated user is a resource-method selector, so OPTIONS has to
> reflect this).
>
> * Your addition: For *authenticated* OPTIONS with "Depth: ..." you can add
> your valueable approach ontop by simply adding Content-Type (e. g.
> "application/allow+xml") and Content-Length headers, and send a list of all
> actually allowed resource-methods in the response's entity. This is a
> perfectly valid addition, implies the reduced roundtrips number you want to
> achieve, and is in no contrast to the pure http style described above.
>

OK, I can see how this can work, may be even JSON, as XML would require
some namespace:

{
   "a":"POST,GET",
   "a/c":"POST,GET,PUT",
}

By the way I would not consider X-OPTIONS or X-BAR being less pure HTTP
than OPTIONS, X-BAR is simply another verb, not known to be the major
HTTP verb, speaking of which,

> So I would really beg you to not only implement your solution as a X-OPTIONS
> implementation, but to instead go with both solutions as two filters. The
> pure http style filter (RolesAllowedOptionsFilter) plus your performance
> improvement filter (RolesAllowedOptionsPerformanceFilter).
>
> BTW, I actually do not see how such a filter could be implemented, as
> ContainerRequestContext seems to miss a method to get the
> java.lang.reflect.Method. Without this, the filter cannot check for
> @RolesAllowed. Seems it is actually impossible for an application programmer
> to code this on his own, without further support of the JAX-RS spec, which
> brings this topic back on the desk...!
>
Believe it or not I'm thinking of providing a CXF filter for doing
something like the above specifically for UI built with say Eclipse,
etc. And I also thought how it would work with JAX-RS, given that
"OPTIONS" with "Depth: infinite" or indeed any other extension such as
X-BAR can not be handled in JAX-RS unless a JAX-RS resource method is
annotated with accepting "X-BAR" or "OPTIONS" which in this case will
not help.

At the moment, the only way it can work if a pre-match filter is
registered and it relies on the implementation-specific metadata to get
the list of root resources, their resource methods and proceed from
there - this is how I plan to implement it when I get to it...

In case of UI getting the 'map' of all the resources and the methods
allowed on them this is all what is needed. Furthermore, IMHO this case
is the same as the task of managing "X-BAR" HTTP verb without the root
resource having to accept "X-BAR". It's like managing the preflight CORS
request and validating early that the runtime actually will be to handle
the actual follow-up request, all without the application code itself
managing the preflight.

Thus I wonder, if one more context, similar to ResourceContext, called
ApplicationContext or whatever that can be injected into a pre-match
filter and provide the info about all the root resources and their
methods, can be introduced ? This will support the case of managing all
sort of extensions in a portable way without the app code having to deal
with them

Cheers, Sergey


> Thanks
> Markus
>