Re: Unauthenticated access returns 204.

2009-12-17 Thread Thierry Boileau
Hello Matt,

I've entered on issue for this topic: 
http://restlet.tigris.org/issues/show_bug.cgi?id=985
Thanks for your report.

Best regards,
Thierry Boileau

> I've always thought that 401 "Not Authorized" was poorly chosen wording, 
> because it really says the same thing as 403 "Forbidden".  However, the 
> requirement that a 401 status also MUST send a WWW-Authenticate header I 
> think in practice has led 401 to really mean "Not Authenticated" and 403 to 
> really mean "Not Authorized". Whereas in the description of 403 in rfc2616 
> section 10 explicitly states that "Authentication will not help", which 
> implies that either no authentication is possible, the user is simply trying 
> to do something the server doesn't want done, or it implies that the user is 
> in fact authenticated, and the server is saying the authenticated user isn't 
> authorized to do that.
>
> So where does that leave us?  I guess I think that the abstract 
> implementation of Authenticator should not simply return 204 to the client if 
> Authentication has been set to be required, and a concrete subclass has 
> returned false in the authenticate() method.  It is OK, because it does in 
> fact stop the filter, but I think it could be a little bit easier on the 
> programmer implementing the concrete subclass.  Perhaps setting the status to 
> 403 is more appropriate in this case.  Anyway, I trust the restlet team's 
> judgement here, but if you decide to keep the behavior as it is, then I 
> encourage you to document clearly that the unauthenticated() method will also 
> need to be overridden in subclasses in order to produce behavior that results 
> in a 401 or 403 upon returning false from the authenticate() method.  I would 
> be happy to look at possible implementations of changing the default behavior 
> if it is something the restlet team thinks would be worthwhile.
>
> The good news is that as far as my current project goes, I have custom 
> subclasses of Authenticators and Authorizers working very well and I really 
> like the new security architecture, I'm just trying to figure out if this 
> particular aspect of the behavior is as simple as it could be.
>
> Thanks for your time,
> Matt
>
> --
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2429029
>
>

--
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2431078


Re: Unauthenticated access returns 204.

2009-12-09 Thread Matt Kennedy
I've always thought that 401 "Not Authorized" was poorly chosen wording, 
because it really says the same thing as 403 "Forbidden".  However, the 
requirement that a 401 status also MUST send a WWW-Authenticate header I think 
in practice has led 401 to really mean "Not Authenticated" and 403 to really 
mean "Not Authorized". Whereas in the description of 403 in rfc2616 section 10 
explicitly states that "Authentication will not help", which implies that 
either no authentication is possible, the user is simply trying to do something 
the server doesn't want done, or it implies that the user is in fact 
authenticated, and the server is saying the authenticated user isn't authorized 
to do that.

So where does that leave us?  I guess I think that the abstract implementation 
of Authenticator should not simply return 204 to the client if Authentication 
has been set to be required, and a concrete subclass has returned false in the 
authenticate() method.  It is OK, because it does in fact stop the filter, but 
I think it could be a little bit easier on the programmer implementing the 
concrete subclass.  Perhaps setting the status to 403 is more appropriate in 
this case.  Anyway, I trust the restlet team's judgement here, but if you 
decide to keep the behavior as it is, then I encourage you to document clearly 
that the unauthenticated() method will also need to be overridden in subclasses 
in order to produce behavior that results in a 401 or 403 upon returning false 
from the authenticate() method.  I would be happy to look at possible 
implementations of changing the default behavior if it is something the restlet 
team thinks would be worthwhile.

The good news is that as far as my current project goes, I have custom 
subclasses of Authenticators and Authorizers working very well and I really 
like the new security architecture, I'm just trying to figure out if this 
particular aspect of the behavior is as simple as it could be.

Thanks for your time,
Matt

--
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2429029


Re: Unauthenticated access returns 204.

2009-12-09 Thread Thierry Boileau
Hi Matt,

basically, an authenticator aims at extracting all interesting data from 
the request in order to authenticate the request, that is to say check 
that the credentials conveyed by the request correspond to a known user. 
The enroler is then used to complete the Request#clientInfo attribute in 
order to give the application all necessary data about the current user.
Another step is to say that this user is authorized according to the 
application policy to access the requested resource (via an authorizer 
filter). If the current user is not authorized, a 401 status code is 
returned.

Having said that, one subclass of Authenticator, called 
ChallengeAuthenticator aims at handling requests based on "challenge 
schemes".
This filter relies on an instance of the Verifier class that checks the 
credentials and authenticates users. In addition, due to the challenge 
mecanism, it ensures that the response to a unauthenticated request 
contains the necessary data (a ChallengeRequest object, corresponding to 
the "WWW-Authenticate" HTTP header) that will help the client to 
understand what happens and to correctly fulfill the next request. Thus, 
the 401 status code is used (perhaps a "unauthenticated request" status 
code would be better).
I should mention that  the DigestAuthenticator class is a subclass of 
ChallengeAuthenticator that specifically handles the case of the 
HTTP_DIGEST challenge scheme.
Of course, this must not be confused with the "authorization" step which 
help to decides if an authenticated user is allowed or not to access 
precisely to a resource.

Best regards,
Thierry Boileau

> I'm trying to implement a custom authenticator class and I'm a little stumped 
> by the behavior so far.  When I override the authenticate() method to always 
> return false, I get back an HTTP 204 error.  However, if I have it always 
> return true, then the request goes through correctly, so I think I have 
> everything wired up the right way.  Based on my reading of the available 
> documentation, if authentication is set as required in the Authenticator 
> subclass (which is the default setting), then a 401 response should be sent.  
> Is this a bug?  Or am I missing a required step in my subclass implementation?
>
> Thanks,
> Matt
>
> The following illustrates the problem (in Groovy):
>
> import org.restlet.*;
> import org.restlet.data.*;
> import org.restlet.security.Authenticator;
> import org.restlet.representation.*;
>
> class TestAuthenticator extends Authenticator
> {
>   @Override 
>   public TestAuthenticator(Context ctx){ super(ctx); }
>
>   @Override
>   protected boolean authenticate(Request request, Response response)
>   {
> return false;
> //return true;
>   }
> }
>
> class TestRestlet extends Restlet
> {
>   @Override
>   public void handle(Request request, Response response) 
>   {
> response.setEntity(new StringRepresentation("hello, world\n", 
> MediaType.TEXT_PLAIN));
>   }
> }
>
> def component = new Component();
> Server http = component.servers.add(Protocol.HTTP, 8181);
> component.clients.add(Protocol.FILE);
> Context workingCtx = http.context;
> def guard = new TestAuthenticator(workingCtx);
> def restlet = new TestRestlet();
> guard.setNext(restlet);
> component.defaultHost.attach(guard);
> component.start();
>
> --
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2426801
>
>

--
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2428784


Re: Unauthenticated access returns 204.

2009-12-08 Thread Matt Kennedy
Stephan, I did call a 204 an error, didn't I?  I should know better.  

I have done some digging and I think I see what's going on. The 
unauthenticated() method in the abstract Authenticator class never sets 
CLIENT_ERROR_UNAUTHORIZED in the response object.  I don't know whether it 
should or not. It makes subclassing Authenticator slightly easier if it does 
set that status.  It seems to me that if authentication is not optional, and it 
gets as far as the unauthenticated() method, then in addition to setting any 
challengeResponse.authenticated property to false and the 
clientInfo.authenticated property to false, the method can go ahead and set the 
status in the response object as well. Otherwise, anybody writing a subclass of 
Authenticator will have to subclass the unauthenticated() method as well in 
order to return a 401.  Which is completely fine, it just isn't as simple.  I'm 
going to get a checkout of svn tomorrow and I'll see if I can make this change 
without breaking anything and submit the code if everything works OK.

-Matt



On Dec 5, 2009, at 8:16 AM, Stephan Koops wrote:

> Hi Matt,
> 
> maybe the reason is, that the status is set to 204, if there is no 
> entity (by Restlet). This must onky be done, if status is 200. Maybe 
> this check is missing. Try to check it with the debugger.
> 
> BTW: 204 is not an error, it means "ok, but no entity available".
> 
> best regards
>   Stephan
> 
> Matt Kennedy schrieb:
>> I'm trying to implement a custom authenticator class and I'm a little 
>> stumped by the behavior so far.  When I override the authenticate() method 
>> to always return false, I get back an HTTP 204 error.  However, if I have it 
>> always return true, then the request goes through correctly, so I think I 
>> have everything wired up the right way.  Based on my reading of the 
>> available documentation, if authentication is set as required in the 
>> Authenticator subclass (which is the default setting), then a 401 response 
>> should be sent.  Is this a bug?  Or am I missing a required step in my 
>> subclass implementation?
>> 
>> Thanks,
>> Matt
>> 
>> The following illustrates the problem (in Groovy):
>> 
>> import org.restlet.*;
>> import org.restlet.data.*;
>> import org.restlet.security.Authenticator;
>> import org.restlet.representation.*;
>> 
>> class TestAuthenticator extends Authenticator
>> {
>>  @Override 
>>  public TestAuthenticator(Context ctx){ super(ctx); }
>> 
>>  @Override
>>  protected boolean authenticate(Request request, Response response)
>>  {
>>return false;
>>//return true;
>>  }
>> }
>> 
>> class TestRestlet extends Restlet
>> {
>>  @Override
>>  public void handle(Request request, Response response) 
>>  {
>>response.setEntity(new StringRepresentation("hello, world\n", 
>> MediaType.TEXT_PLAIN));
>>  }
>> }
>> 
>> def component = new Component();
>> Server http = component.servers.add(Protocol.HTTP, 8181);
>> component.clients.add(Protocol.FILE);
>> Context workingCtx = http.context;
>> def guard = new TestAuthenticator(workingCtx);
>> def restlet = new TestRestlet();
>> guard.setNext(restlet);
>> component.defaultHost.attach(guard);
>> component.start();
>> 
>> --
>> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2426801
>> 
> 
> --
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2427447

--
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2428725

Re: Unauthenticated access returns 204.

2009-12-05 Thread Stephan Koops
Hi Matt,

maybe the reason is, that the status is set to 204, if there is no 
entity (by Restlet). This must onky be done, if status is 200. Maybe 
this check is missing. Try to check it with the debugger.

BTW: 204 is not an error, it means "ok, but no entity available".

best regards
   Stephan

Matt Kennedy schrieb:
> I'm trying to implement a custom authenticator class and I'm a little stumped 
> by the behavior so far.  When I override the authenticate() method to always 
> return false, I get back an HTTP 204 error.  However, if I have it always 
> return true, then the request goes through correctly, so I think I have 
> everything wired up the right way.  Based on my reading of the available 
> documentation, if authentication is set as required in the Authenticator 
> subclass (which is the default setting), then a 401 response should be sent.  
> Is this a bug?  Or am I missing a required step in my subclass implementation?
>
> Thanks,
> Matt
>
> The following illustrates the problem (in Groovy):
>
> import org.restlet.*;
> import org.restlet.data.*;
> import org.restlet.security.Authenticator;
> import org.restlet.representation.*;
>
> class TestAuthenticator extends Authenticator
> {
>   @Override 
>   public TestAuthenticator(Context ctx){ super(ctx); }
>
>   @Override
>   protected boolean authenticate(Request request, Response response)
>   {
> return false;
> //return true;
>   }
> }
>
> class TestRestlet extends Restlet
> {
>   @Override
>   public void handle(Request request, Response response) 
>   {
> response.setEntity(new StringRepresentation("hello, world\n", 
> MediaType.TEXT_PLAIN));
>   }
> }
>
> def component = new Component();
> Server http = component.servers.add(Protocol.HTTP, 8181);
> component.clients.add(Protocol.FILE);
> Context workingCtx = http.context;
> def guard = new TestAuthenticator(workingCtx);
> def restlet = new TestRestlet();
> guard.setNext(restlet);
> component.defaultHost.attach(guard);
> component.start();
>
> --
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2426801
>

--
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2427447