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

Reply via email to