Hi,
Replying to my own post here as the answer was markedly more simple than I
imagined.
As a recap I needed a mechanism to populate the ChallengeResponse objects
with values extracted from requests using the Amazon S3 authentication
scheme.
Since I don't need send any true challenge or response to the user beyond
a 403 if access is forbidden the implementation was as simple as the
following:
package transport.rest ;
import org.restlet.Request ;
import org.restlet.data.ChallengeResponse ;
import org.restlet.data.ChallengeScheme ;
import org.restlet.data.Parameter ;
import org.restlet.util.Series ;
import org.restlet.engine.security.AuthenticatorHelper ;
/**
* Parse the values received from an Amazon S3 client using the AWS
* scheme in the HTTP Authorization header.
*/
class S3AuthenticatorHelper extends AuthenticatorHelper
{
/**
* Constructor. Registers this helper for client-side S3 authentication.
*/
public S3AuthenticatorHelper()
{
super(ChallengeScheme.HTTP_AWS_S3, true, false) ;
} //ctor
/**
* Parse the Authorization header into the user and hash
*components.
* The user is held in identifier, the hash in secret.
*/
@Override
public void parseResponse( ChallengeResponse challenge, Request
request, Series<Parameter> httpHeaders)
{
// Get the raw string and break it on the : seperator
String raw = challenge.getRawValue() ;
challenge.setIdentifier(raw.substring(0, raw.indexOf(":"))) ;
// This is read as a char[] on getSecret -- be careful!
challenge.setSecret(raw.substring(raw.indexOf(":")+1,
raw.length())) ;
} //parseResponse
} //class
Then in the main class of my app, where I create/start Components and such
I added:
org.restlet.engine.Engine.getInstance().getRegisteredAuthenticators.add(
new S3AuthenticatorHelper()) ;
Hope that helps someone else who is as confused as I was!
Cheers,
Garry
On Mon, 11 Jan 2010, Garry Turkington wrote:
> Hi,
>
> I've got an app that gets a custom value in the HTTP Authorization
> request header. So far I've wrote an Authenticator that checks the
> validity of the provided values by parsing the Authorization header
> contents.
>
> There are then 3 different types of authorization rules depending on
> the URI pattern so I've 3 Authorizer subclasses set as routes from the
> authenticator which themselves link back to the actual resource
> subclasses. Logic in these authorizers again uses the contents of the
> Authorization header to look up the user in ACLs on the resources.
>
> Which is all well and good and pretty much works. But I'm getting
> warnings logged as the Authorization header value is non-standard and
> no built-in mechanism knows how to parse the value. I'm not using any
> of the ChallengeResponse or related classes currently but poking
> around in the code I see that the base Authenticator class tries to
> parse the Authorization header and in my case it fails.
>
> The values in my Authorization header don't really map into the
> standard attributes on the ChallengeResponse object, it's basically a
> user id and a hash. But on a quick look it appears to be non-trivial
> to add the custom code to do the parsing to provide these as say
> ChallengeResponse#user and ChallengeResponse#secret.
>
> Being quite new to Restlet I'm perhaps getting confused between some
> 1.0 and 2.0 classes as it appeared to me that I need subclass
> org.restlet.engine.security.AuthenticationHelper but that seemed
> contrary to the newer org.restlet.security classes.
>
> Can anyone elaborate?
>
> Thanks,
> Garry
>
> ------------------------------------------------------
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2436427
>
--
Garry Turkington
[email protected]
------------------------------------------------------
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2439872