Hi,
I also think that it is not a good solution to recreate the
Authorization header, e.g. for security reasons. It also requires, that
you add a special Guard to your Restlet chain, which only would convert
the header back to a ChallengeResponse.
What are the arguments againt my first proposal?
And I plan to support also the Servlet role management to be used from
JAX-RS. Are there some plans? If not, I propose to move the RoleChecker
interface or something like it in the Core Restlet API and save an
instance of it in the request attributes or where ever, so that any
application could use the capability supported by the connector.
What do you all think?
best regards
Stephan
Bruno Harbulot wrote:
Jerome Louvel wrote:
The simplest is to modify ServletCall#getRequestHeaders() to
automatically
add an "Authorization" HTTP header.
[Double check that this header is not already forwarded by the Servlet
container]
I'm not sure it's a good idea to add an Authorization HTTP header
when it wasn't present in the client's request.
Some people who were fairly knowledgeable in terms of security got
bitten at this game:
https://spaces.internet2.edu/display/SHIB/SpoofingBug
In short, this authz module was adding a header to propagate
information further down the chain (from Apache), but didn't reset
the header it would normally set up when it wouldn't have added it.
Then, you need to recreate the original value of the header, called
the raw
credentials.
For that, you have access to the challenge scheme via getAuthType()
and to
the user's identifier via getRemoteUser(). For the password, you
could try
using an empty or special constant value like "unknown".
Then there is a static
com.noelios.restlet.authentication.AuthenticationUtils#format(ChallengeRespo
nse challenge, Request request, Series<Parameter> httpHeaders)
method that
will do the rest of the job for you.
You may have troubles with the "FORM" scheme though. We may need to add
special support for that as a pluggable authentication scheme
provided by
the Servlet extension (not really hard).
I thought the problem was only to get the authentication method name
(FORM/BASIC/DIGEST/CERT) and thus propagate an equivalent to
HttpServletRequest.getAuthType().
I reckon this is only a problem for FORM, since it's possible to find
out about the other ones from the original headers that will be
passed on anyway (BASIC/DIGEST) or from the certificate attribute
(SSL client auth).
Rather than putting this piece of information into the Form that
holds the HTTP headers, I'd put it directly as an attribute of the
request, that is:
- request.getAttributes().put(...SOME...NAME..., x)
instead of:
- headerForm.add(new Parameter("Authorization", "FORM");
request.getAttributes().put(HttpConstants.ATTRIBUTE_HEADERS,
headerForm)
I'm not really sure what the best way to do this is, though, in
particular whether it should be done for all types of request or just
for this specific type (i.e. only set it from ServletCall and only if
it's using FORM authentication).
I don't think it's currently possible to set specific attributes of
HttpRequest from an HttpServerCall (in particular ServletCall), since
all attributes of HttpRequest seem to be set up by
HttpServerConverter which calls out to the methods of HttpServerCall
(none of which seem to be able to set up some attribute specific to
them that would be passed to the HttpRequest attributes directly).
I know the solution I've describe may not be ideal, but I prefer it to
adding an made-up authorisation HTTP header. Applications that would
use it wouldn't be able to tell the difference between "Authorization:
" set up internally or set up by the client.
Unlike the Shibboleth example, which was making up its own specific
header (and thus was able to fix its problem by clearing it anyway),
the Authorization header is actually legitimate in most cases and it
could be set up by the client, so it would be harder to know when to
clear it and when not to.
Best wishes,
Bruno.