Setting Connection header in m7
Hi, I'm sure I'm just missing something obvious in the API but how do I set the Connection header on responses in M7 and the snapshot? M6 seemed to set Connection to close which is what some of my clients need. With the async model in M7 and beyond I'm assume I need explicitly set this but can't find out where. Pointers? Thanks, Garry -- Garry Turkington garry.turking...@gmail.com -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2443284
Re: Comprehensive example of authentication in RESTLet 2.0?
Hi Drew, I can't give a comprehensive example but I just built something along these lines recently and actually found the main building blocks to be quite straightforward. I have a number of routes configured in my application, the first object in each is a custom class that extends org.restlet.security.Authenticator. That class has an authenticate method that receives the request and response objects and returns a boolean result -- though you also need set the status code on the response if it's a non 200-code situation. Within that method I check the custom values of the ChallengeResponse object that my AuthenticationHelper populates (see below) to make coarse authentication decisions. The next objects in my routes are then different subclasses of org.restlet.security.Authorizer that have an authorize method analogous to the authenticate method in the Authenticator. By this mechanism I have logic that has parsed the header into the user credentials, made a decision if this is a valid user and decided if they can use the resource before the resource is ever touched. Re the AuthenticationHelper, I was initially confused by this but for me it was easier than I expected. I wrote a subclass of org.restlet.engine.security.AuthenticatorHelper and overrode the parseResponse method. This method receives the raw bytes from the Authorization header in the request and its in this method that I take this and use it to populate the ChallengeResponse object used by the authenticator. So this is where you could do your database lookups to convert the raw auth data into fields on the ChallengeResponse object that the Authenticator will then use for its authentication decisions. AuthenticationHelper has a bunch of other methods depending on whether or not you've got more elaborate auth schemes but for me all I needed do was implement the one method. You do need register the helper and this is where I can't help you. I was receiving requests using the Amazon S3 authentication scheme and that's specified as a type in org.restlet.ChallengeScheme. I'm not sure how you register with a custom scheme. The one thing I did find was that once I had my custom Authenticator, Authorizer and AuthenticationHelper classes it all just worked; the Restlet machinery calls the right methods at the right times and you get the outcomes you want. It's pretty cool. Hope that helps a little, Garry On Tue, 26 Jan 2010, Drew wrote: Hello, I'm trying to integrate authentication into my RESTLets however I'm having trouble understanding the authentication scheme that Restlet implements. It seems that most of the examples use the Guard class... however this is now deprecated... It seems that ChallengeAuthenticator should be used instead. Also, most of the examples only show simple password validation. How would we extend this to using a database? I understand there are AuthenticationHelpers... how do these fit in? It seems there are many powerful features we can use but I'm having trouble understanding how to use them all together. I guess I'm having trouble understanding how these big pieces fit together... as most of the examples seem to be overly simplistic. If you could point me in the right direction on how to use the 2.0 authentication features I'd much appreciate it. Thanks -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2442326 -- Garry Turkington garry.turking...@gmail.com -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2442849
Duplicate custom headers in snapshot
Hi, In my ServerResource subclasses I need set some custom response headers. I use code like the following: Form f = (Form)getResponse().getAttributes().get(org.restlet.http.headers) ; f.add( new Parameter( x-app-header, value)) ; Which works fine in the 2.0M6 release but in the snapshot all the headers are duplicated. If I set 3 headers then the response that is sent has them in order twice. Is the mechanism to set custom headers different in the snapshot or is this a known issue? Regards, Garry -- Garry Turkington garry.turking...@gmail.com -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2442295
Lifecycle of message attributes
Hi, In one route in my app I've got an Authenticator, two chained Authorizers and then a ServerResource resource instance. As part of the authentication and authorization processes -- not to mention the actual servicing of the request -- I need pull some objects from a backing store, currently a database. Obviously I don't want to be doing this 4 times each call and was trying to add the object into the message attributes for reuse, e.g.: request.getAttributes().put(myobj, obj) ; The problem is that I can't reliably then pull this object back within the next object in the route. In some cases it's worked, in others it hasn't. For the sake of getting things working I've been taking the hit of the 4 database calls but obviously that's not a long-term solution. I'll have an internal object cache which will cut out the additional db round trips but that's not finished yet and I want to understand what's going on. So is there some aspect of the lifecycle of attributes added to a message that I'm missing here? Does it make any difference if components in the route are added by setNext(instance) as opposed to setNext(class literal)? Thanks, Garry -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2441383
Re: Lifecycle of message attributes
Hi, Replying to my own post as it was a serious case of user error. In particular, using a slightly inconsistent name for the objects put into and then pulled from the message attributes can cause very strange behaviour... Feel free to laugh at my expense. :) Regards, Garry On Sat, 23 Jan 2010, Garry Turkington wrote: Hi, In one route in my app I've got an Authenticator, two chained Authorizers and then a ServerResource resource instance. As part of the authentication and authorization processes -- not to mention the actual servicing of the request -- I need pull some objects from a backing store, currently a database. Obviously I don't want to be doing this 4 times each call and was trying to add the object into the message attributes for reuse, e.g.: request.getAttributes().put(myobj, obj) ; The problem is that I can't reliably then pull this object back within the next object in the route. In some cases it's worked, in others it hasn't. For the sake of getting things working I've been taking the hit of the 4 database calls but obviously that's not a long-term solution. I'll have an internal object cache which will cut out the additional db round trips but that's not finished yet and I want to understand what's going on. So is there some aspect of the lifecycle of attributes added to a message that I'm missing here? Does it make any difference if components in the route are added by setNext(instance) as opposed to setNext(class literal)? Thanks, Garry -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2441383 -- Garry Turkington garry.turking...@gmail.com -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2441411
Re: Advice re parsing custom Authorization values
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, SeriesParameter 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=4447dsMessageId=2436427 -- Garry Turkington garry.turking...@gmail.com -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2439872
Re: Restlet client and setting the request header date
Hi again Thierry, One other question re the removal of the onContinue callbacks. In the snapshot code I was trying to use the interim response code to support an Expect/CONTINUE interaction. I wasn't getting the behaviour I expected though on reflection I wasn't convinced the client I had was doing the right thing. So if onContinue has gone away what is the client-side mechanism for receiving and responding to an interim response? My use case is the client sending the headers of a PUT request and the server sending a CONTINUE only if the stated size of the entity is acceptable. Thanks, Garry On Thu, 14 Jan 2010, Thierry Boileau wrote: Hi Garry, I'm afraid not. This value is set with a new Date() value just before the header is written... The onContinue was thought to be called before the entity is sent, after the headers were written. I say was, because it has been removed since no clear use case emerged. Best regards, Thierry Boileau Hi, I too hit this problem as I wanted to set a specific value for the Date header. In absence of this ability -- I've seen issue 1001 -- can I get the value of the header client side before the request is sent in any way? I want to set another header based on the date. I thought that setting a Uniform instance as the oncontinue handler of the ClientResource would allow this but the handle() method in Uniform doesn't seem to be called before the request is actually sent? Thanks, Garry -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2436971 -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2437281 -- Garry Turkington garry.turking...@gmail.com -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2437399
Re: Restlet client and setting the request header date
Hi Thierry, Thanks for this response, even if it does make my life more complicated! What I'm building is basically a clone of Amazon's S3. On the server side this has been more or less fine using Restlet -- modulo the issues I've previously raised re the AuthenticationHelper and support for Expect/CONTINUE -- but it looks like I'll not be able to build a Restlet-based client. Which makes me ask what the point is of the support for the S3 scheme in ChallengeResponse? The values in that scheme are dependent on being able to read and sign actual header values such as Date. I read the Javadoc for onContinue and when it said it was called before the entity was sent I wasn't sure just how literal that was. Not sure about that use case but for my purposes a callback prior to the dispatch of the entire request that would allow examination and modification of the actual request (both headers and entity) to be sent would be really useful. Cheers, Garry On Thu, 14 Jan 2010, Thierry Boileau wrote: Hi Garry, I'm afraid not. This value is set with a new Date() value just before the header is written... The onContinue was thought to be called before the entity is sent, after the headers were written. I say was, because it has been removed since no clear use case emerged. Best regards, Thierry Boileau Hi, I too hit this problem as I wanted to set a specific value for the Date header. In absence of this ability -- I've seen issue 1001 -- can I get the value of the header client side before the request is sent in any way? I want to set another header based on the date. I thought that setting a Uniform instance as the oncontinue handler of the ClientResource would allow this but the handle() method in Uniform doesn't seem to be called before the request is actually sent? Thanks, Garry -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2436971 -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2437281 -- Garry Turkington garry.turking...@gmail.com -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2437392
RE: Restlet client and setting the request header date
Hi, I too hit this problem as I wanted to set a specific value for the Date header. In absence of this ability -- I've seen issue 1001 -- can I get the value of the header client side before the request is sent in any way? I want to set another header based on the date. I thought that setting a Uniform instance as the oncontinue handler of the ClientResource would allow this but the handle() method in Uniform doesn't seem to be called before the request is actually sent? Thanks, Garry -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2436971