CookieAuthenticator for Restlet 2.3.4

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

CookieAuthenticator for Restlet 2.3.4

xrgarcia3
I have built some api's using RESTLET 2.3.4 and i'm using http basic using the browser to prompt for login.  It's time for a proper login form so I want to implement CookieAuthenticator.  I have it partially working, and i'm stuck.

Here is the gist.  My have a subclass of CookieAuthenticator.  The constructor specifics the loginPath to '/login'.  The application adds a route to '/login' and the class is a LoginResource.class.  I'm not sure what to implement in this class.

If you could point me to a working example or shed some light you would be most helpful.

To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: CookieAuthenticator for Restlet 2.3.4

Tim Peierls
On Wed, Sep 2, 2015 at 2:31 PM, Ray Garcia <[hidden email]> wrote:
Here is the gist.  My have a subclass of CookieAuthenticator.  The constructor specifics the loginPath to '/login'.  The application adds a route to '/login' and the class is a LoginResource.class.  I'm not sure what to implement in this class.

If you could point me to a working example or shed some light you would be most helpful.

 
Best I can do with limited time is point you to a post I made about 20 months ago, which in turn has pointers to even earlier posts of mine. I believe that some of the hacks I did are no longer necessary.



---------- Forwarded message ----------
From: Tim Peierls <[hidden email]>
Date: Sun, Jan 5, 2014 at 1:32 PM
Subject: Re: Authenticator for multiple authentication schemes
To: discuss <[hidden email]>


Looking at older conversations about this, it might be a failure to override the login form path. Failing that, I can only offer examples of what works for me.

I had to extend CookieAuthenticator to provide standard challenge behavior. I still use this extension (further extended for my purposes), but it might not be necessary any more:


Here's a Restlet application to serve login and logout resources and a login form resource:


LoginFormResource in my case just serves a Freemarker template representation of a login form:


The Freemarker template is something like this:


HTH


On Fri, Jan 3, 2014 at 9:31 AM, Fabian Mandelbaum <[hidden email]> wrote:
Hello there,

I've updated to Reslet 2.2-M6, replaced my HTTP Basic Guard with CookieAuthenticator, and when trying to access a guarded resource, instead of the login dialog I got HTTP 401 and this on logs:

2014-01-03 11:25:24 0:0:0:0:0:0:0:1%0 - 0:0:0:0:0:0:0:1%0 9000 GET /res/dojo-release/dijit/themes/claro/images/tooltipGradient.png - 200 - 0 6 http://localhost:9000 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:26.0) Gecko/20100101 Firefox/26.0 http://localhost:9000/res/dojo-release/dijit/themes/claro/claro.css

2014-01-03 11:25:25 0:0:0:0:0:0:0:1%0 - 0:0:0:0:0:0:0:1%0 9000 GET /workspaces/ - 401 424 0 http://localhost:9000 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:26.0) Gecko/20100101 Firefox/26.0 http://localhost:9000/

Challenge scheme HTTP_Cookie not supported by the Restlet engine.

2014-01-03 11:25:25 0:0:0:0:0:0:0:1%0 - 0:0:0:0:0:0:0:1%0 9000 GET /favicon.ico - 401 424 0 http://localhost:9000 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:26.0) Gecko/20100101 Firefox/26.0 -

Challenge scheme HTTP_Cookie not supported by the Restlet engine.

2014-01-03 11:25:25 0:0:0:0:0:0:0:1%0 - 0:0:0:0:0:0:0:1%0 9000 GET /favicon.ico - 401 424 0 http://localhost:9000 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:26.0) Gecko/20100101 Firefox/26.0 -

Challenge scheme HTTP_Cookie not supported by the Restlet engine.

What's going on? What am I doing wrong?

Thanks in advance for your help.




On Fri, Jan 3, 2014 at 7:53 AM, Fabián Mandelbaum <[hidden email]> wrote:
Hello Tim,

thanks for your answers.

I've tried, using the example in the Restlet IN ACTION book as a guide, what you proposed, the two chained authenticators, and it does not work.

I've chained them like this:

cookieauth -> httpauth -> guarded_resources

I'll test with Restlet 2.2 today, though I don't know if we can switch our stable project to the still unstable Restlet 2.2...

BTW, Restlet ppl, any idea on when 2.2 will become 'final'? The roadmap page on the Restlet website states Q3 2013... and that's about 3 months ago now...

Thanks.


On Thu, Jan 2, 2014 at 3:32 PM, Tim Peierls <[hidden email]> wrote:
Not sure how much of this works in Restlet 2.1 -- I use CookieAuthenticator successfully with Restlet 2.2.


On Thu, Jan 2, 2014 at 1:32 PM, Tim Peierls <[hidden email]> wrote:
It should be possible to chain two different Authenticator instances, with optional = true on the first, and multiAuthenticating = false on the second. If the first one succeeds, the second should see ClientInfo.isAuthenticated() == true and bypass its operation. If the first one fails, the second one sees ClientInfo.isAuthenticated() == false and does not bypass its operation. 

But before you try that, consider using CookieAuthenticator -- much of the implementation is parameterized and/or overridable.


On Thu, Jan 2, 2014 at 7:29 AM, Fabian Mandelbaum <[hidden email]> wrote:
Hello there,

our Restlet-based application needs to have users authenticated using both cookies and http basic (hopefully to be switched to digest soon) authentication (Actually it's either cookies or http auth, but see below for auth flow). We also use our own verifier storing credentials on JCR and set it as the defaultVerifier() for the app's context in createInboundRoot().

I've seen that the ChallengeAuthenticator class only accepts one authentication method on its constructor so, a priori, one cannot have a Guard that uses more than one auth method.

The authentication workflow with the Guard/Authenticator our app needs would be something like this:

1) If cookie is present, verify it
2) if cookie verification passes, all OK, continue processing request
3) if cookie verification fails, use HTTP authentication

Is this possible with Restlet 2.1?

I'd appreciate any guide/pointer/idea you may have. Thanks in advance.

To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: CookieAuthenticator for Restlet 2.3.4

xrgarcia3
Tim,
Thank you for your response.  I did get this working after stepping through the debugger.  Here is what i did:

1. Create ServerResources with an EMPTY method annotated with @POST.  The logic for handling this is in the CookieAuthenticator filter, filter being the key word.  So i added these empty resources to my router and added my cookieAuthenticator to them:
// login/logout
router.attach(“/login",createCookieGuard(LoginEndPoint.class));
router.attach(“/logout", createCookieGuard(LogoutEndPoint.class));
2. So i noticed the beforeHandle method wasn’t detecting the login process so i overwrote the isLoggingIn method to properly compare value i set for setLoginPath:
@Override
protected boolean isLoggingIn(Request request, Response response) {
boolean isLoggingIn = isInterceptingLogin();
String loginPath = getLoginPath();
String requestedPath = request.getResourceRef().getPath();
return isLoggingIn
&& loginPath
.equals(requestedPath)
&& Method.POST.equals(request.getMethod());
}
3. Same with Logout
protected boolean isLoggingOut(Request request, Response response) {
boolean isLoggingOut = isInterceptingLogout();
String logoutPath = getLogoutPath();
String requestedPath = request.getResourceRef().getPath();
return isLoggingOut
&&
logoutPath.equals(requestedPath)
&& (Method.GET.equals(request.getMethod()) || Method.POST
.equals(request.getMethod()));
}
I could be doing this unecessarily but i didn’t see a good example in the documentation.  My next objective is to send back error=true to the login.html via a query parameter.
It would be best to include a working example in the restlet.com user guide and distribution.  Do you need assistance or do you have it covered?
Thanks again for your help.
-ray



On Wed, Sep 2, 2015 at 2:31 PM, Ray Garcia <[hidden email]> wrote:
Here is the gist.  My have a subclass of CookieAuthenticator.  The constructor specifics the loginPath to '/login'.  The application adds a route to '/login' and the class is a LoginResource.class.  I'm not sure what to implement in this class.

If you could point me to a working example or shed some light you would be most helpful.

 
Best I can do with limited time is point you to a post I made about 20 months ago, which in turn has pointers to even earlier posts of mine. I believe that some of the hacks I did are no longer necessary.



---------- Forwarded message ----------
From: Tim Peierls <[hidden email]>
Date: Sun, Jan 5, 2014 at 1:32 PM
Subject: Re: Authenticator for multiple authentication schemes
To: discuss <[hidden email]>


Looking at older conversations about this, it might be a failure to override the login form path. Failing that, I can only offer examples of what works for me.

I had to extend CookieAuthenticator to provide standard challenge behavior. I still use this extension (further extended for my purposes), but it might not be necessary any more:


Here's a Restlet application to serve login and logout resources and a login form resource:


LoginFormResource in my case just serves a Freemarker template representation of a login form:


The Freemarker template is something like this:


HTH


On Fri, Jan 3, 2014 at 9:31 AM, Fabian Mandelbaum <[hidden email]> wrote:
Hello there,

I've updated to Reslet 2.2-M6, replaced my HTTP Basic Guard with CookieAuthenticator, and when trying to access a guarded resource, instead of the login dialog I got HTTP 401 and this on logs:

2014-01-03 11:25:24 0:0:0:0:0:0:0:1%0 - 0:0:0:0:0:0:0:1%0 9000 GET /res/dojo-release/dijit/themes/claro/images/tooltipGradient.png - 200 - 0 6 http://localhost:9000 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:26.0) Gecko/20100101 Firefox/26.0 http://localhost:9000/res/dojo-release/dijit/themes/claro/claro.css

2014-01-03 11:25:25 0:0:0:0:0:0:0:1%0 - 0:0:0:0:0:0:0:1%0 9000 GET /workspaces/ - 401 424 0 http://localhost:9000 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:26.0) Gecko/20100101 Firefox/26.0 http://localhost:9000/

Challenge scheme HTTP_Cookie not supported by the Restlet engine.

2014-01-03 11:25:25 0:0:0:0:0:0:0:1%0 - 0:0:0:0:0:0:0:1%0 9000 GET /favicon.ico - 401 424 0 http://localhost:9000 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:26.0) Gecko/20100101 Firefox/26.0 -

Challenge scheme HTTP_Cookie not supported by the Restlet engine.

2014-01-03 11:25:25 0:0:0:0:0:0:0:1%0 - 0:0:0:0:0:0:0:1%0 9000 GET /favicon.ico - 401 424 0 http://localhost:9000 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:26.0) Gecko/20100101 Firefox/26.0 -

Challenge scheme HTTP_Cookie not supported by the Restlet engine.

What's going on? What am I doing wrong?

Thanks in advance for your help.




On Fri, Jan 3, 2014 at 7:53 AM, Fabián Mandelbaum <[hidden email]> wrote:
Hello Tim,

thanks for your answers.

I've tried, using the example in the Restlet IN ACTION book as a guide, what you proposed, the two chained authenticators, and it does not work.

I've chained them like this:

cookieauth -> httpauth -> guarded_resources

I'll test with Restlet 2.2 today, though I don't know if we can switch our stable project to the still unstable Restlet 2.2...

BTW, Restlet ppl, any idea on when 2.2 will become 'final'? The roadmap page on the Restlet website states Q3 2013... and that's about 3 months ago now...

Thanks.


On Thu, Jan 2, 2014 at 3:32 PM, Tim Peierls <[hidden email]> wrote:
Not sure how much of this works in Restlet 2.1 -- I use CookieAuthenticator successfully with Restlet 2.2.


On Thu, Jan 2, 2014 at 1:32 PM, Tim Peierls <[hidden email]> wrote:
It should be possible to chain two different Authenticator instances, with optional = true on the first, and multiAuthenticating = false on the second. If the first one succeeds, the second should see ClientInfo.isAuthenticated() == true and bypass its operation. If the first one fails, the second one sees ClientInfo.isAuthenticated() == false and does not bypass its operation. 

But before you try that, consider using CookieAuthenticator -- much of the implementation is parameterized and/or overridable.


On Thu, Jan 2, 2014 at 7:29 AM, Fabian Mandelbaum <[hidden email]> wrote:
Hello there,

our Restlet-based application needs to have users authenticated using both cookies and http basic (hopefully to be switched to digest soon) authentication (Actually it's either cookies or http auth, but see below for auth flow). We also use our own verifier storing credentials on JCR and set it as the defaultVerifier() for the app's context in createInboundRoot().

I've seen that the ChallengeAuthenticator class only accepts one authentication method on its constructor so, a priori, one cannot have a Guard that uses more than one auth method.

The authentication workflow with the Guard/Authenticator our app needs would be something like this:

1) If cookie is present, verify it
2) if cookie verification passes, all OK, continue processing request
3) if cookie verification fails, use HTTP authentication

Is this possible with Restlet 2.1?

I'd appreciate any guide/pointer/idea you may have. Thanks in advance.

To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: CookieAuthenticator for Restlet 2.3.4

Tim Peierls

I have had everything working nicely for a few years now. Some day, if I have time, I'll try to document what I did in a generic and reusable way.

On Sep 3, 2015 3:04 PM, "Ray Garcia" <[hidden email]> wrote:
Tim,
Thank you for your response.  I did get this working after stepping through the debugger.  Here is what i did:

1. Create ServerResources with an EMPTY method annotated with @POST.  The logic for handling this is in the CookieAuthenticator filter, filter being the key word.  So i added these empty resources to my router and added my cookieAuthenticator to them:
// login/logout
router.attach(“/login",createCookieGuard(LoginEndPoint.class));
router.attach(“/logout", createCookieGuard(LogoutEndPoint.class));
2. So i noticed the beforeHandle method wasn’t detecting the login process so i overwrote the isLoggingIn method to properly compare value i set for setLoginPath:
@Override
protected boolean isLoggingIn(Request request, Response response) {
boolean isLoggingIn = isInterceptingLogin();
String loginPath = getLoginPath();
String requestedPath = request.getResourceRef().getPath();
return isLoggingIn
&& loginPath
.equals(requestedPath)
&& Method.POST.equals(request.getMethod());
}
3. Same with Logout
protected boolean isLoggingOut(Request request, Response response) {
boolean isLoggingOut = isInterceptingLogout();
String logoutPath = getLogoutPath();
String requestedPath = request.getResourceRef().getPath();
return isLoggingOut
&&
logoutPath.equals(requestedPath)
&& (Method.GET.equals(request.getMethod()) || Method.POST
.equals(request.getMethod()));
}
I could be doing this unecessarily but i didn’t see a good example in the documentation.  My next objective is to send back error=true to the login.html via a query parameter.
It would be best to include a working example in the restlet.com user guide and distribution.  Do you need assistance or do you have it covered?
Thanks again for your help.
-ray



On Wed, Sep 2, 2015 at 2:31 PM, Ray Garcia <[hidden email]> wrote:
Here is the gist.  My have a subclass of CookieAuthenticator.  The constructor specifics the loginPath to '/login'.  The application adds a route to '/login' and the class is a LoginResource.class.  I'm not sure what to implement in this class.

If you could point me to a working example or shed some light you would be most helpful.

 
Best I can do with limited time is point you to a post I made about 20 months ago, which in turn has pointers to even earlier posts of mine. I believe that some of the hacks I did are no longer necessary.



---------- Forwarded message ----------
From: Tim Peierls <[hidden email]>
Date: Sun, Jan 5, 2014 at 1:32 PM
Subject: Re: Authenticator for multiple authentication schemes
To: discuss <[hidden email]>


Looking at older conversations about this, it might be a failure to override the login form path. Failing that, I can only offer examples of what works for me.

I had to extend CookieAuthenticator to provide standard challenge behavior. I still use this extension (further extended for my purposes), but it might not be necessary any more:


Here's a Restlet application to serve login and logout resources and a login form resource:


LoginFormResource in my case just serves a Freemarker template representation of a login form:


The Freemarker template is something like this:


HTH


On Fri, Jan 3, 2014 at 9:31 AM, Fabian Mandelbaum <[hidden email]> wrote:
Hello there,

I've updated to Reslet 2.2-M6, replaced my HTTP Basic Guard with CookieAuthenticator, and when trying to access a guarded resource, instead of the login dialog I got HTTP 401 and this on logs:

2014-01-03 11:25:24 0:0:0:0:0:0:0:1%0 - 0:0:0:0:0:0:0:1%0 9000 GET /res/dojo-release/dijit/themes/claro/images/tooltipGradient.png - 200 - 0 6 http://localhost:9000 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:26.0) Gecko/20100101 Firefox/26.0 http://localhost:9000/res/dojo-release/dijit/themes/claro/claro.css

2014-01-03 11:25:25 0:0:0:0:0:0:0:1%0 - 0:0:0:0:0:0:0:1%0 9000 GET /workspaces/ - 401 424 0 http://localhost:9000 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:26.0) Gecko/20100101 Firefox/26.0 http://localhost:9000/

Challenge scheme HTTP_Cookie not supported by the Restlet engine.

2014-01-03 11:25:25 0:0:0:0:0:0:0:1%0 - 0:0:0:0:0:0:0:1%0 9000 GET /favicon.ico - 401 424 0 http://localhost:9000 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:26.0) Gecko/20100101 Firefox/26.0 -

Challenge scheme HTTP_Cookie not supported by the Restlet engine.

2014-01-03 11:25:25 0:0:0:0:0:0:0:1%0 - 0:0:0:0:0:0:0:1%0 9000 GET /favicon.ico - 401 424 0 http://localhost:9000 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:26.0) Gecko/20100101 Firefox/26.0 -

Challenge scheme HTTP_Cookie not supported by the Restlet engine.

What's going on? What am I doing wrong?

Thanks in advance for your help.




On Fri, Jan 3, 2014 at 7:53 AM, Fabián Mandelbaum <[hidden email]> wrote:
Hello Tim,

thanks for your answers.

I've tried, using the example in the Restlet IN ACTION book as a guide, what you proposed, the two chained authenticators, and it does not work.

I've chained them like this:

cookieauth -> httpauth -> guarded_resources

I'll test with Restlet 2.2 today, though I don't know if we can switch our stable project to the still unstable Restlet 2.2...

BTW, Restlet ppl, any idea on when 2.2 will become 'final'? The roadmap page on the Restlet website states Q3 2013... and that's about 3 months ago now...

Thanks.


On Thu, Jan 2, 2014 at 3:32 PM, Tim Peierls <[hidden email]> wrote:
Not sure how much of this works in Restlet 2.1 -- I use CookieAuthenticator successfully with Restlet 2.2.


On Thu, Jan 2, 2014 at 1:32 PM, Tim Peierls <[hidden email]> wrote:
It should be possible to chain two different Authenticator instances, with optional = true on the first, and multiAuthenticating = false on the second. If the first one succeeds, the second should see ClientInfo.isAuthenticated() == true and bypass its operation. If the first one fails, the second one sees ClientInfo.isAuthenticated() == false and does not bypass its operation. 

But before you try that, consider using CookieAuthenticator -- much of the implementation is parameterized and/or overridable.


On Thu, Jan 2, 2014 at 7:29 AM, Fabian Mandelbaum <[hidden email]> wrote:
Hello there,

our Restlet-based application needs to have users authenticated using both cookies and http basic (hopefully to be switched to digest soon) authentication (Actually it's either cookies or http auth, but see below for auth flow). We also use our own verifier storing credentials on JCR and set it as the defaultVerifier() for the app's context in createInboundRoot().

I've seen that the ChallengeAuthenticator class only accepts one authentication method on its constructor so, a priori, one cannot have a Guard that uses more than one auth method.

The authentication workflow with the Guard/Authenticator our app needs would be something like this:

1) If cookie is present, verify it
2) if cookie verification passes, all OK, continue processing request
3) if cookie verification fails, use HTTP authentication

Is this possible with Restlet 2.1?

I'd appreciate any guide/pointer/idea you may have. Thanks in advance.

To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].

To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: CookieAuthenticator for Restlet 2.3.4

Thierry Boileau-4
Hello Ray and Tim,

I think that setting up two resources for login and logout is unnecessary, or in other words, the CookieAuthenticator class has been designed to be very easy to use as illustrated by Tim's sample code: https://gist.github.com/Tembrel/8271674

That is to say: one public resource for serving the login form, all the other resources are routed behind the CookieAuthenticator which intercepts all requests to the "/login" or "/logout" urls.

Having said that, I have one question for Tim. I'm a little bit troubled by the logic of CookieAuthenticator#beforeHandle.
In case of logout, the CookieAuthenticator computes a redirect response and stops the handling flow.
In case of login, the CookieAuthenticator computes a redirect response but keep the current flow which leads to the error pointed by Ray. Ray set up two resources with a ampty method annotated @POST.
I think we should stop the flow once the redirect response has been computed, just as the logout.

I guess I have missed something, but I don't know what.

Best regards,
Thierry


2015-09-03 21:29 GMT+02:00 Tim Peierls <[hidden email]>:

I have had everything working nicely for a few years now. Some day, if I have time, I'll try to document what I did in a generic and reusable way.

On Sep 3, 2015 3:04 PM, "Ray Garcia" <[hidden email]> wrote:
Tim,
Thank you for your response.  I did get this working after stepping through the debugger.  Here is what i did:

1. Create ServerResources with an EMPTY method annotated with @POST.  The logic for handling this is in the CookieAuthenticator filter, filter being the key word.  So i added these empty resources to my router and added my cookieAuthenticator to them:
// login/logout
router.attach(“/login",createCookieGuard(LoginEndPoint.class));
router.attach(“/logout", createCookieGuard(LogoutEndPoint.class));
2. So i noticed the beforeHandle method wasn’t detecting the login process so i overwrote the isLoggingIn method to properly compare value i set for setLoginPath:
@Override
protected boolean isLoggingIn(Request request, Response response) {
boolean isLoggingIn = isInterceptingLogin();
String loginPath = getLoginPath();
String requestedPath = request.getResourceRef().getPath();
return isLoggingIn
&& loginPath
.equals(requestedPath)
&& Method.POST.equals(request.getMethod());
}
3. Same with Logout
protected boolean isLoggingOut(Request request, Response response) {
boolean isLoggingOut = isInterceptingLogout();
String logoutPath = getLogoutPath();
String requestedPath = request.getResourceRef().getPath();
return isLoggingOut
&&
logoutPath.equals(requestedPath)
&& (Method.GET.equals(request.getMethod()) || Method.POST
.equals(request.getMethod()));
}
I could be doing this unecessarily but i didn’t see a good example in the documentation.  My next objective is to send back error=true to the login.html via a query parameter.
It would be best to include a working example in the restlet.com user guide and distribution.  Do you need assistance or do you have it covered?
Thanks again for your help.
-ray



On Wed, Sep 2, 2015 at 2:31 PM, Ray Garcia <[hidden email]> wrote:
Here is the gist.  My have a subclass of CookieAuthenticator.  The constructor specifics the loginPath to '/login'.  The application adds a route to '/login' and the class is a LoginResource.class.  I'm not sure what to implement in this class.

If you could point me to a working example or shed some light you would be most helpful.

 
Best I can do with limited time is point you to a post I made about 20 months ago, which in turn has pointers to even earlier posts of mine. I believe that some of the hacks I did are no longer necessary.



---------- Forwarded message ----------
From: Tim Peierls <[hidden email]>
Date: Sun, Jan 5, 2014 at 1:32 PM
Subject: Re: Authenticator for multiple authentication schemes
To: discuss <[hidden email]>


Looking at older conversations about this, it might be a failure to override the login form path. Failing that, I can only offer examples of what works for me.

I had to extend CookieAuthenticator to provide standard challenge behavior. I still use this extension (further extended for my purposes), but it might not be necessary any more:


Here's a Restlet application to serve login and logout resources and a login form resource:


LoginFormResource in my case just serves a Freemarker template representation of a login form:


The Freemarker template is something like this:


HTH


On Fri, Jan 3, 2014 at 9:31 AM, Fabian Mandelbaum <[hidden email]> wrote:
Hello there,

I've updated to Reslet 2.2-M6, replaced my HTTP Basic Guard with CookieAuthenticator, and when trying to access a guarded resource, instead of the login dialog I got HTTP 401 and this on logs:

2014-01-03 11:25:24 0:0:0:0:0:0:0:1%0 - 0:0:0:0:0:0:0:1%0 9000 GET /res/dojo-release/dijit/themes/claro/images/tooltipGradient.png - 200 - 0 6 http://localhost:9000 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:26.0) Gecko/20100101 Firefox/26.0 http://localhost:9000/res/dojo-release/dijit/themes/claro/claro.css

2014-01-03 11:25:25 0:0:0:0:0:0:0:1%0 - 0:0:0:0:0:0:0:1%0 9000 GET /workspaces/ - 401 424 0 http://localhost:9000 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:26.0) Gecko/20100101 Firefox/26.0 http://localhost:9000/

Challenge scheme HTTP_Cookie not supported by the Restlet engine.

2014-01-03 11:25:25 0:0:0:0:0:0:0:1%0 - 0:0:0:0:0:0:0:1%0 9000 GET /favicon.ico - 401 424 0 http://localhost:9000 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:26.0) Gecko/20100101 Firefox/26.0 -

Challenge scheme HTTP_Cookie not supported by the Restlet engine.

2014-01-03 11:25:25 0:0:0:0:0:0:0:1%0 - 0:0:0:0:0:0:0:1%0 9000 GET /favicon.ico - 401 424 0 http://localhost:9000 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:26.0) Gecko/20100101 Firefox/26.0 -

Challenge scheme HTTP_Cookie not supported by the Restlet engine.

What's going on? What am I doing wrong?

Thanks in advance for your help.




On Fri, Jan 3, 2014 at 7:53 AM, Fabián Mandelbaum <[hidden email]> wrote:
Hello Tim,

thanks for your answers.

I've tried, using the example in the Restlet IN ACTION book as a guide, what you proposed, the two chained authenticators, and it does not work.

I've chained them like this:

cookieauth -> httpauth -> guarded_resources

I'll test with Restlet 2.2 today, though I don't know if we can switch our stable project to the still unstable Restlet 2.2...

BTW, Restlet ppl, any idea on when 2.2 will become 'final'? The roadmap page on the Restlet website states Q3 2013... and that's about 3 months ago now...

Thanks.


On Thu, Jan 2, 2014 at 3:32 PM, Tim Peierls <[hidden email]> wrote:
Not sure how much of this works in Restlet 2.1 -- I use CookieAuthenticator successfully with Restlet 2.2.


On Thu, Jan 2, 2014 at 1:32 PM, Tim Peierls <[hidden email]> wrote:
It should be possible to chain two different Authenticator instances, with optional = true on the first, and multiAuthenticating = false on the second. If the first one succeeds, the second should see ClientInfo.isAuthenticated() == true and bypass its operation. If the first one fails, the second one sees ClientInfo.isAuthenticated() == false and does not bypass its operation. 

But before you try that, consider using CookieAuthenticator -- much of the implementation is parameterized and/or overridable.


On Thu, Jan 2, 2014 at 7:29 AM, Fabian Mandelbaum <[hidden email]> wrote:
Hello there,

our Restlet-based application needs to have users authenticated using both cookies and http basic (hopefully to be switched to digest soon) authentication (Actually it's either cookies or http auth, but see below for auth flow). We also use our own verifier storing credentials on JCR and set it as the defaultVerifier() for the app's context in createInboundRoot().

I've seen that the ChallengeAuthenticator class only accepts one authentication method on its constructor so, a priori, one cannot have a Guard that uses more than one auth method.

The authentication workflow with the Guard/Authenticator our app needs would be something like this:

1) If cookie is present, verify it
2) if cookie verification passes, all OK, continue processing request
3) if cookie verification fails, use HTTP authentication

Is this possible with Restlet 2.1?

I'd appreciate any guide/pointer/idea you may have. Thanks in advance.

To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].



--
Thierry Boileau, Mr B


6 Rue Rose Dieng-Kuntz • Nantes, 44300  France

To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: CookieAuthenticator for Restlet 2.3.4

Tim Peierls
Here's an updated version of the default implementation of CookieAuthenticator that I now use as a base class for further extension:


The key difference with my previous version (which is very close to what is currently in the Restlet codebase) is the presence of code to handle a login failure. It looks as though I added it to be able to distinguish on the login form between first attempts and subsequent attempts (to display an informational message in the latter case) -- which is one of Ray's concerns as well. 

At any rate, your (Thierry's) idea of adding adding a return value (of Filter.STOP) to the login logic in CA#beforeHandle seems good to me. It looks as though by isolating the authentication-related resources in their own application and using a null Restlet for all requests except the login form -- https://gist.github.com/Tembrel/8271674 -- I'm simulating a Filter.STOP. This seems similar to what Ray is doing, except that his version doesn't need to be isolated in its own application.

Here's the subclass I use in practice:


I don't see anything in this that affects the default logic, though.


On Sat, Sep 5, 2015 at 9:49 AM, Thierry Boileau <[hidden email]> wrote:
Hello Ray and Tim,

I think that setting up two resources for login and logout is unnecessary, or in other words, the CookieAuthenticator class has been designed to be very easy to use as illustrated by Tim's sample code: https://gist.github.com/Tembrel/8271674

That is to say: one public resource for serving the login form, all the other resources are routed behind the CookieAuthenticator which intercepts all requests to the "/login" or "/logout" urls.

Having said that, I have one question for Tim. I'm a little bit troubled by the logic of CookieAuthenticator#beforeHandle.
In case of logout, the CookieAuthenticator computes a redirect response and stops the handling flow.
In case of login, the CookieAuthenticator computes a redirect response but keep the current flow which leads to the error pointed by Ray. Ray set up two resources with a ampty method annotated @POST.
I think we should stop the flow once the redirect response has been computed, just as the logout.

I guess I have missed something, but I don't know what.

Best regards,
Thierry


2015-09-03 21:29 GMT+02:00 Tim Peierls <[hidden email]>:

I have had everything working nicely for a few years now. Some day, if I have time, I'll try to document what I did in a generic and reusable way.

On Sep 3, 2015 3:04 PM, "Ray Garcia" <[hidden email]> wrote:
Tim,
Thank you for your response.  I did get this working after stepping through the debugger.  Here is what i did:

1. Create ServerResources with an EMPTY method annotated with @POST.  The logic for handling this is in the CookieAuthenticator filter, filter being the key word.  So i added these empty resources to my router and added my cookieAuthenticator to them:
// login/logout
router.attach(“/login",createCookieGuard(LoginEndPoint.class));
router.attach(“/logout", createCookieGuard(LogoutEndPoint.class));
2. So i noticed the beforeHandle method wasn’t detecting the login process so i overwrote the isLoggingIn method to properly compare value i set for setLoginPath:
@Override
protected boolean isLoggingIn(Request request, Response response) {
boolean isLoggingIn = isInterceptingLogin();
String loginPath = getLoginPath();
String requestedPath = request.getResourceRef().getPath();
return isLoggingIn
&& loginPath
.equals(requestedPath)
&& Method.POST.equals(request.getMethod());
}
3. Same with Logout
protected boolean isLoggingOut(Request request, Response response) {
boolean isLoggingOut = isInterceptingLogout();
String logoutPath = getLogoutPath();
String requestedPath = request.getResourceRef().getPath();
return isLoggingOut
&&
logoutPath.equals(requestedPath)
&& (Method.GET.equals(request.getMethod()) || Method.POST
.equals(request.getMethod()));
}
I could be doing this unecessarily but i didn’t see a good example in the documentation.  My next objective is to send back error=true to the login.html via a query parameter.
It would be best to include a working example in the restlet.com user guide and distribution.  Do you need assistance or do you have it covered?
Thanks again for your help.
-ray



On Wed, Sep 2, 2015 at 2:31 PM, Ray Garcia <[hidden email]> wrote:
Here is the gist.  My have a subclass of CookieAuthenticator.  The constructor specifics the loginPath to '/login'.  The application adds a route to '/login' and the class is a LoginResource.class.  I'm not sure what to implement in this class.

If you could point me to a working example or shed some light you would be most helpful.

 
Best I can do with limited time is point you to a post I made about 20 months ago, which in turn has pointers to even earlier posts of mine. I believe that some of the hacks I did are no longer necessary.



---------- Forwarded message ----------
From: Tim Peierls <[hidden email]>
Date: Sun, Jan 5, 2014 at 1:32 PM
Subject: Re: Authenticator for multiple authentication schemes
To: discuss <[hidden email]>


Looking at older conversations about this, it might be a failure to override the login form path. Failing that, I can only offer examples of what works for me.

I had to extend CookieAuthenticator to provide standard challenge behavior. I still use this extension (further extended for my purposes), but it might not be necessary any more:


Here's a Restlet application to serve login and logout resources and a login form resource:


LoginFormResource in my case just serves a Freemarker template representation of a login form:


The Freemarker template is something like this:


HTH


On Fri, Jan 3, 2014 at 9:31 AM, Fabian Mandelbaum <[hidden email]> wrote:
Hello there,

I've updated to Reslet 2.2-M6, replaced my HTTP Basic Guard with CookieAuthenticator, and when trying to access a guarded resource, instead of the login dialog I got HTTP 401 and this on logs:

2014-01-03 11:25:24 0:0:0:0:0:0:0:1%0 - 0:0:0:0:0:0:0:1%0 9000 GET /res/dojo-release/dijit/themes/claro/images/tooltipGradient.png - 200 - 0 6 http://localhost:9000 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:26.0) Gecko/20100101 Firefox/26.0 http://localhost:9000/res/dojo-release/dijit/themes/claro/claro.css

2014-01-03 11:25:25 0:0:0:0:0:0:0:1%0 - 0:0:0:0:0:0:0:1%0 9000 GET /workspaces/ - 401 424 0 http://localhost:9000 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:26.0) Gecko/20100101 Firefox/26.0 http://localhost:9000/

Challenge scheme HTTP_Cookie not supported by the Restlet engine.

2014-01-03 11:25:25 0:0:0:0:0:0:0:1%0 - 0:0:0:0:0:0:0:1%0 9000 GET /favicon.ico - 401 424 0 http://localhost:9000 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:26.0) Gecko/20100101 Firefox/26.0 -

Challenge scheme HTTP_Cookie not supported by the Restlet engine.

2014-01-03 11:25:25 0:0:0:0:0:0:0:1%0 - 0:0:0:0:0:0:0:1%0 9000 GET /favicon.ico - 401 424 0 http://localhost:9000 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:26.0) Gecko/20100101 Firefox/26.0 -

Challenge scheme HTTP_Cookie not supported by the Restlet engine.

What's going on? What am I doing wrong?

Thanks in advance for your help.




On Fri, Jan 3, 2014 at 7:53 AM, Fabián Mandelbaum <[hidden email]> wrote:
Hello Tim,

thanks for your answers.

I've tried, using the example in the Restlet IN ACTION book as a guide, what you proposed, the two chained authenticators, and it does not work.

I've chained them like this:

cookieauth -> httpauth -> guarded_resources

I'll test with Restlet 2.2 today, though I don't know if we can switch our stable project to the still unstable Restlet 2.2...

BTW, Restlet ppl, any idea on when 2.2 will become 'final'? The roadmap page on the Restlet website states Q3 2013... and that's about 3 months ago now...

Thanks.


On Thu, Jan 2, 2014 at 3:32 PM, Tim Peierls <[hidden email]> wrote:
Not sure how much of this works in Restlet 2.1 -- I use CookieAuthenticator successfully with Restlet 2.2.


On Thu, Jan 2, 2014 at 1:32 PM, Tim Peierls <[hidden email]> wrote:
It should be possible to chain two different Authenticator instances, with optional = true on the first, and multiAuthenticating = false on the second. If the first one succeeds, the second should see ClientInfo.isAuthenticated() == true and bypass its operation. If the first one fails, the second one sees ClientInfo.isAuthenticated() == false and does not bypass its operation. 

But before you try that, consider using CookieAuthenticator -- much of the implementation is parameterized and/or overridable.


On Thu, Jan 2, 2014 at 7:29 AM, Fabian Mandelbaum <[hidden email]> wrote:
Hello there,

our Restlet-based application needs to have users authenticated using both cookies and http basic (hopefully to be switched to digest soon) authentication (Actually it's either cookies or http auth, but see below for auth flow). We also use our own verifier storing credentials on JCR and set it as the defaultVerifier() for the app's context in createInboundRoot().

I've seen that the ChallengeAuthenticator class only accepts one authentication method on its constructor so, a priori, one cannot have a Guard that uses more than one auth method.

The authentication workflow with the Guard/Authenticator our app needs would be something like this:

1) If cookie is present, verify it
2) if cookie verification passes, all OK, continue processing request
3) if cookie verification fails, use HTTP authentication

Is this possible with Restlet 2.1?

I'd appreciate any guide/pointer/idea you may have. Thanks in advance.

To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].



--
Thierry Boileau, Mr B


6 Rue Rose Dieng-Kuntz • Nantes, 44300  France

To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].

To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: CookieAuthenticator for Restlet 2.3.4

xrgarcia3
Tim/Thierry,
Thank you for the much needed clarification.  My confussion initally is the documentation implies (from my view at least) the developer will secure all of their services with CookieAuthenticator.  I only secure some of them because I want users to create accounts without being logged in, fill drop down lists, or fill web pages with content.  In this case i don’t see a way around adding empty Login/Logout resource.  Correct me if i’m wrong!

Kind Regards,
-ray
  




On Sat, Sep 5, 2015 at 10:13 AM, Tim Peierls <[hidden email]> wrote:

Here's an updated version of the default implementation of CookieAuthenticator that I now use as a base class for further extension:


The key difference with my previous version (which is very close to what is currently in the Restlet codebase) is the presence of code to handle a login failure. It looks as though I added it to be able to distinguish on the login form between first attempts and subsequent attempts (to display an informational message in the latter case) -- which is one of Ray's concerns as well. 

At any rate, your (Thierry's) idea of adding adding a return value (of Filter.STOP) to the login logic in CA#beforeHandle seems good to me. It looks as though by isolating the authentication-related resources in their own application and using a null Restlet for all requests except the login form -- https://gist.github.com/Tembrel/8271674 -- I'm simulating a Filter.STOP. This seems similar to what Ray is doing, except that his version doesn't need to be isolated in its own application.

Here's the subclass I use in practice:


I don't see anything in this that affects the default logic, though.


On Sat, Sep 5, 2015 at 9:49 AM, Thierry Boileau <[hidden email]> wrote:
Hello Ray and Tim,

I think that setting up two resources for login and logout is unnecessary, or in other words, the CookieAuthenticator class has been designed to be very easy to use as illustrated by Tim's sample code: https://gist.github.com/Tembrel/8271674

That is to say: one public resource for serving the login form, all the other resources are routed behind the CookieAuthenticator which intercepts all requests to the "/login" or "/logout" urls.

Having said that, I have one question for Tim. I'm a little bit troubled by the logic of CookieAuthenticator#beforeHandle.
In case of logout, the CookieAuthenticator computes a redirect response and stops the handling flow.
In case of login, the CookieAuthenticator computes a redirect response but keep the current flow which leads to the error pointed by Ray. Ray set up two resources with a ampty method annotated @POST.
I think we should stop the flow once the redirect response has been computed, just as the logout.

I guess I have missed something, but I don't know what.

Best regards,
Thierry


2015-09-03 21:29 GMT+02:00 Tim Peierls <[hidden email]>:

I have had everything working nicely for a few years now. Some day, if I have time, I'll try to document what I did in a generic and reusable way.

On Sep 3, 2015 3:04 PM, "Ray Garcia" <[hidden email]> wrote:
Tim,
Thank you for your response.  I did get this working after stepping through the debugger.  Here is what i did:

1. Create ServerResources with an EMPTY method annotated with @POST.  The logic for handling this is in the CookieAuthenticator filter, filter being the key word.  So i added these empty resources to my router and added my cookieAuthenticator to them:
// login/logout
router.attach(“/login",createCookieGuard(LoginEndPoint.class));
router.attach(“/logout", createCookieGuard(LogoutEndPoint.class));
2. So i noticed the beforeHandle method wasn’t detecting the login process so i overwrote the isLoggingIn method to properly compare value i set for setLoginPath:
@Override
protected boolean isLoggingIn(Request request, Response response) {
boolean isLoggingIn = isInterceptingLogin();
String loginPath = getLoginPath();
String requestedPath = request.getResourceRef().getPath();
return isLoggingIn
&& loginPath
.equals(requestedPath)
&& Method.POST.equals(request.getMethod());
}
3. Same with Logout
protected boolean isLoggingOut(Request request, Response response) {
boolean isLoggingOut = isInterceptingLogout();
String logoutPath = getLogoutPath();
String requestedPath = request.getResourceRef().getPath();
return isLoggingOut
&&
logoutPath.equals(requestedPath)
&& (Method.GET.equals(request.getMethod()) || Method.POST
.equals(request.getMethod()));
}
I could be doing this unecessarily but i didn’t see a good example in the documentation.  My next objective is to send back error=true to the login.html via a query parameter.
It would be best to include a working example in the restlet.com user guide and distribution.  Do you need assistance or do you have it covered?
Thanks again for your help.
-ray



On Wed, Sep 2, 2015 at 2:31 PM, Ray Garcia <[hidden email]> wrote:
Here is the gist.  My have a subclass of CookieAuthenticator.  The constructor specifics the loginPath to '/login'.  The application adds a route to '/login' and the class is a LoginResource.class.  I'm not sure what to implement in this class.

If you could point me to a working example or shed some light you would be most helpful.

 
Best I can do with limited time is point you to a post I made about 20 months ago, which in turn has pointers to even earlier posts of mine. I believe that some of the hacks I did are no longer necessary.



---------- Forwarded message ----------
From: Tim Peierls <[hidden email]>
Date: Sun, Jan 5, 2014 at 1:32 PM
Subject: Re: Authenticator for multiple authentication schemes
To: discuss <[hidden email]>


Looking at older conversations about this, it might be a failure to override the login form path. Failing that, I can only offer examples of what works for me.

I had to extend CookieAuthenticator to provide standard challenge behavior. I still use this extension (further extended for my purposes), but it might not be necessary any more:


Here's a Restlet application to serve login and logout resources and a login form resource:


LoginFormResource in my case just serves a Freemarker template representation of a login form:


The Freemarker template is something like this:


HTH


On Fri, Jan 3, 2014 at 9:31 AM, Fabian Mandelbaum <[hidden email]> wrote:
Hello there,

I've updated to Reslet 2.2-M6, replaced my HTTP Basic Guard with CookieAuthenticator, and when trying to access a guarded resource, instead of the login dialog I got HTTP 401 and this on logs:

2014-01-03 11:25:24 0:0:0:0:0:0:0:1%0 - 0:0:0:0:0:0:0:1%0 9000 GET /res/dojo-release/dijit/themes/claro/images/tooltipGradient.png - 200 - 0 6 http://localhost:9000 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:26.0) Gecko/20100101 Firefox/26.0 http://localhost:9000/res/dojo-release/dijit/themes/claro/claro.css

2014-01-03 11:25:25 0:0:0:0:0:0:0:1%0 - 0:0:0:0:0:0:0:1%0 9000 GET /workspaces/ - 401 424 0 http://localhost:9000 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:26.0) Gecko/20100101 Firefox/26.0 http://localhost:9000/

Challenge scheme HTTP_Cookie not supported by the Restlet engine.

2014-01-03 11:25:25 0:0:0:0:0:0:0:1%0 - 0:0:0:0:0:0:0:1%0 9000 GET /favicon.ico - 401 424 0 http://localhost:9000 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:26.0) Gecko/20100101 Firefox/26.0 -

Challenge scheme HTTP_Cookie not supported by the Restlet engine.

2014-01-03 11:25:25 0:0:0:0:0:0:0:1%0 - 0:0:0:0:0:0:0:1%0 9000 GET /favicon.ico - 401 424 0 http://localhost:9000 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:26.0) Gecko/20100101 Firefox/26.0 -

Challenge scheme HTTP_Cookie not supported by the Restlet engine.

What's going on? What am I doing wrong?

Thanks in advance for your help.




On Fri, Jan 3, 2014 at 7:53 AM, Fabián Mandelbaum <[hidden email]> wrote:
Hello Tim,

thanks for your answers.

I've tried, using the example in the Restlet IN ACTION book as a guide, what you proposed, the two chained authenticators, and it does not work.

I've chained them like this:

cookieauth -> httpauth -> guarded_resources

I'll test with Restlet 2.2 today, though I don't know if we can switch our stable project to the still unstable Restlet 2.2...

BTW, Restlet ppl, any idea on when 2.2 will become 'final'? The roadmap page on the Restlet website states Q3 2013... and that's about 3 months ago now...

Thanks.


On Thu, Jan 2, 2014 at 3:32 PM, Tim Peierls <[hidden email]> wrote:
Not sure how much of this works in Restlet 2.1 -- I use CookieAuthenticator successfully with Restlet 2.2.


On Thu, Jan 2, 2014 at 1:32 PM, Tim Peierls <[hidden email]> wrote:
It should be possible to chain two different Authenticator instances, with optional = true on the first, and multiAuthenticating = false on the second. If the first one succeeds, the second should see ClientInfo.isAuthenticated() == true and bypass its operation. If the first one fails, the second one sees ClientInfo.isAuthenticated() == false and does not bypass its operation. 

But before you try that, consider using CookieAuthenticator -- much of the implementation is parameterized and/or overridable.


On Thu, Jan 2, 2014 at 7:29 AM, Fabian Mandelbaum <[hidden email]> wrote:
Hello there,

our Restlet-based application needs to have users authenticated using both cookies and http basic (hopefully to be switched to digest soon) authentication (Actually it's either cookies or http auth, but see below for auth flow). We also use our own verifier storing credentials on JCR and set it as the defaultVerifier() for the app's context in createInboundRoot().

I've seen that the ChallengeAuthenticator class only accepts one authentication method on its constructor so, a priori, one cannot have a Guard that uses more than one auth method.

The authentication workflow with the Guard/Authenticator our app needs would be something like this:

1) If cookie is present, verify it
2) if cookie verification passes, all OK, continue processing request
3) if cookie verification fails, use HTTP authentication

Is this possible with Restlet 2.1?

I'd appreciate any guide/pointer/idea you may have. Thanks in advance.

To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].



--
Thierry Boileau, Mr B


6 Rue Rose Dieng-Kuntz • Nantes, 44300  France

To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].


To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: CookieAuthenticator for Restlet 2.3.4

Tim Peierls
Without the change that Thierry is proposing, you need some kind of empty resource to serve as the "next" Restlet for the filter.

I did this by creating a separate application just for authentication that sends all requests other than the one to the login form to a simple Restlet that does nothing: https://gist.github.com/Tembrel/8271674

Then I use an instance of CookieAuthenticator for each resource that I want to authenticate in other applications:

// in createInboundRoot in some other application:

    router.attach("/public", PublicResource.class);
    router.attach("/private", guarded(PrivateResource.class));

// where the guarded method is defined something like this:

    Restlet guarded(Class<? extends ServerResource> targetClass) {
        Authenticator auth = new CustomAuthenticator(...);
        auth.setNext(targetClass);
        return auth;
    }

This takes advantage of the fact that many routing-related methods are overloaded to take either a Restlet or a resource class.

--tim

On Sat, Sep 5, 2015 at 1:33 PM, Ray Garcia <[hidden email]> wrote:
Tim/Thierry,
Thank you for the much needed clarification.  My confussion initally is the documentation implies (from my view at least) the developer will secure all of their services with CookieAuthenticator.  I only secure some of them because I want users to create accounts without being logged in, fill drop down lists, or fill web pages with content.  In this case i don’t see a way around adding empty Login/Logout resource.  Correct me if i’m wrong!

Kind Regards,
-ray
  




On Sat, Sep 5, 2015 at 10:13 AM, Tim Peierls <[hidden email]> wrote:

Here's an updated version of the default implementation of CookieAuthenticator that I now use as a base class for further extension:


The key difference with my previous version (which is very close to what is currently in the Restlet codebase) is the presence of code to handle a login failure. It looks as though I added it to be able to distinguish on the login form between first attempts and subsequent attempts (to display an informational message in the latter case) -- which is one of Ray's concerns as well. 

At any rate, your (Thierry's) idea of adding adding a return value (of Filter.STOP) to the login logic in CA#beforeHandle seems good to me. It looks as though by isolating the authentication-related resources in their own application and using a null Restlet for all requests except the login form -- https://gist.github.com/Tembrel/8271674 -- I'm simulating a Filter.STOP. This seems similar to what Ray is doing, except that his version doesn't need to be isolated in its own application.

Here's the subclass I use in practice:


I don't see anything in this that affects the default logic, though.


On Sat, Sep 5, 2015 at 9:49 AM, Thierry Boileau <[hidden email]> wrote:
Hello Ray and Tim,

I think that setting up two resources for login and logout is unnecessary, or in other words, the CookieAuthenticator class has been designed to be very easy to use as illustrated by Tim's sample code: https://gist.github.com/Tembrel/8271674

That is to say: one public resource for serving the login form, all the other resources are routed behind the CookieAuthenticator which intercepts all requests to the "/login" or "/logout" urls.

Having said that, I have one question for Tim. I'm a little bit troubled by the logic of CookieAuthenticator#beforeHandle.
In case of logout, the CookieAuthenticator computes a redirect response and stops the handling flow.
In case of login, the CookieAuthenticator computes a redirect response but keep the current flow which leads to the error pointed by Ray. Ray set up two resources with a ampty method annotated @POST.
I think we should stop the flow once the redirect response has been computed, just as the logout.

I guess I have missed something, but I don't know what.

Best regards,
Thierry


2015-09-03 21:29 GMT+02:00 Tim Peierls <[hidden email]>:

I have had everything working nicely for a few years now. Some day, if I have time, I'll try to document what I did in a generic and reusable way.

On Sep 3, 2015 3:04 PM, "Ray Garcia" <[hidden email]> wrote:
Tim,
Thank you for your response.  I did get this working after stepping through the debugger.  Here is what i did:

1. Create ServerResources with an EMPTY method annotated with @POST.  The logic for handling this is in the CookieAuthenticator filter, filter being the key word.  So i added these empty resources to my router and added my cookieAuthenticator to them:
// login/logout
router.attach(“/login",createCookieGuard(LoginEndPoint.class));
router.attach(“/logout", createCookieGuard(LogoutEndPoint.class));
2. So i noticed the beforeHandle method wasn’t detecting the login process so i overwrote the isLoggingIn method to properly compare value i set for setLoginPath:
@Override
protected boolean isLoggingIn(Request request, Response response) {
boolean isLoggingIn = isInterceptingLogin();
String loginPath = getLoginPath();
String requestedPath = request.getResourceRef().getPath();
return isLoggingIn
&& loginPath
.equals(requestedPath)
&& Method.POST.equals(request.getMethod());
}
3. Same with Logout
protected boolean isLoggingOut(Request request, Response response) {
boolean isLoggingOut = isInterceptingLogout();
String logoutPath = getLogoutPath();
String requestedPath = request.getResourceRef().getPath();
return isLoggingOut
&&
logoutPath.equals(requestedPath)
&& (Method.GET.equals(request.getMethod()) || Method.POST
.equals(request.getMethod()));
}
I could be doing this unecessarily but i didn’t see a good example in the documentation.  My next objective is to send back error=true to the login.html via a query parameter.
It would be best to include a working example in the restlet.com user guide and distribution.  Do you need assistance or do you have it covered?
Thanks again for your help.
-ray



On Wed, Sep 2, 2015 at 2:31 PM, Ray Garcia <[hidden email]> wrote:
Here is the gist.  My have a subclass of CookieAuthenticator.  The constructor specifics the loginPath to '/login'.  The application adds a route to '/login' and the class is a LoginResource.class.  I'm not sure what to implement in this class.

If you could point me to a working example or shed some light you would be most helpful.

 
Best I can do with limited time is point you to a post I made about 20 months ago, which in turn has pointers to even earlier posts of mine. I believe that some of the hacks I did are no longer necessary.



---------- Forwarded message ----------
From: Tim Peierls <[hidden email]>
Date: Sun, Jan 5, 2014 at 1:32 PM
Subject: Re: Authenticator for multiple authentication schemes
To: discuss <[hidden email]>


Looking at older conversations about this, it might be a failure to override the login form path. Failing that, I can only offer examples of what works for me.

I had to extend CookieAuthenticator to provide standard challenge behavior. I still use this extension (further extended for my purposes), but it might not be necessary any more:


Here's a Restlet application to serve login and logout resources and a login form resource:


LoginFormResource in my case just serves a Freemarker template representation of a login form:


The Freemarker template is something like this:


HTH


On Fri, Jan 3, 2014 at 9:31 AM, Fabian Mandelbaum <[hidden email]> wrote:
Hello there,

I've updated to Reslet 2.2-M6, replaced my HTTP Basic Guard with CookieAuthenticator, and when trying to access a guarded resource, instead of the login dialog I got HTTP 401 and this on logs:

2014-01-03 11:25:24 0:0:0:0:0:0:0:1%0 - 0:0:0:0:0:0:0:1%0 9000 GET /res/dojo-release/dijit/themes/claro/images/tooltipGradient.png - 200 - 0 6 http://localhost:9000 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:26.0) Gecko/20100101 Firefox/26.0 http://localhost:9000/res/dojo-release/dijit/themes/claro/claro.css

2014-01-03 11:25:25 0:0:0:0:0:0:0:1%0 - 0:0:0:0:0:0:0:1%0 9000 GET /workspaces/ - 401 424 0 http://localhost:9000 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:26.0) Gecko/20100101 Firefox/26.0 http://localhost:9000/

Challenge scheme HTTP_Cookie not supported by the Restlet engine.

2014-01-03 11:25:25 0:0:0:0:0:0:0:1%0 - 0:0:0:0:0:0:0:1%0 9000 GET /favicon.ico - 401 424 0 http://localhost:9000 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:26.0) Gecko/20100101 Firefox/26.0 -

Challenge scheme HTTP_Cookie not supported by the Restlet engine.

2014-01-03 11:25:25 0:0:0:0:0:0:0:1%0 - 0:0:0:0:0:0:0:1%0 9000 GET /favicon.ico - 401 424 0 http://localhost:9000 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:26.0) Gecko/20100101 Firefox/26.0 -

Challenge scheme HTTP_Cookie not supported by the Restlet engine.

What's going on? What am I doing wrong?

Thanks in advance for your help.




On Fri, Jan 3, 2014 at 7:53 AM, Fabián Mandelbaum <[hidden email]> wrote:
Hello Tim,

thanks for your answers.

I've tried, using the example in the Restlet IN ACTION book as a guide, what you proposed, the two chained authenticators, and it does not work.

I've chained them like this:

cookieauth -> httpauth -> guarded_resources

I'll test with Restlet 2.2 today, though I don't know if we can switch our stable project to the still unstable Restlet 2.2...

BTW, Restlet ppl, any idea on when 2.2 will become 'final'? The roadmap page on the Restlet website states Q3 2013... and that's about 3 months ago now...

Thanks.


On Thu, Jan 2, 2014 at 3:32 PM, Tim Peierls <[hidden email]> wrote:
Not sure how much of this works in Restlet 2.1 -- I use CookieAuthenticator successfully with Restlet 2.2.


On Thu, Jan 2, 2014 at 1:32 PM, Tim Peierls <[hidden email]> wrote:
It should be possible to chain two different Authenticator instances, with optional = true on the first, and multiAuthenticating = false on the second. If the first one succeeds, the second should see ClientInfo.isAuthenticated() == true and bypass its operation. If the first one fails, the second one sees ClientInfo.isAuthenticated() == false and does not bypass its operation. 

But before you try that, consider using CookieAuthenticator -- much of the implementation is parameterized and/or overridable.


On Thu, Jan 2, 2014 at 7:29 AM, Fabian Mandelbaum <[hidden email]> wrote:
Hello there,

our Restlet-based application needs to have users authenticated using both cookies and http basic (hopefully to be switched to digest soon) authentication (Actually it's either cookies or http auth, but see below for auth flow). We also use our own verifier storing credentials on JCR and set it as the defaultVerifier() for the app's context in createInboundRoot().

I've seen that the ChallengeAuthenticator class only accepts one authentication method on its constructor so, a priori, one cannot have a Guard that uses more than one auth method.

The authentication workflow with the Guard/Authenticator our app needs would be something like this:

1) If cookie is present, verify it
2) if cookie verification passes, all OK, continue processing request
3) if cookie verification fails, use HTTP authentication

Is this possible with Restlet 2.1?

I'd appreciate any guide/pointer/idea you may have. Thanks in advance.

To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].



--
Thierry Boileau, Mr B


6 Rue Rose Dieng-Kuntz • Nantes, 44300  France

To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].


To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].

To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
Loading...