Re: How to use CookieAuthenticator?
Hi all, Finally I got it work. As I guessed, it is very simple to setup. The restlet is a great framework which is always easy to setup. We don't need to do anything for loginPath. It will be automatically taken care by CookieAuthenticator. I stuck to setup, because of a small usability/understanding issue. The LoginFormPath also trying for authentication. It should be skip by default. Because of this my browser became unresponsive because of infinite loop. I suggest, the default implementation of beforeHandle() method of CookieAuthenticator might be as below, protected int beforeHandle(Request request, Response response) { * if (request.getResourceRef().getRemainingPart().equals(getLoginFormPath())) { return CONTINUE; }else {* if (isLoggingIn(request, response)) { login(request, response); } else if (isLoggingOut(request, response)) { return logout(request, response); } return super.beforeHandle(request, response); } *}* Below are the working code of my application: 1. PTCookieAuthenticator.java public class PTCookieAuthenticator extends CookieAuthenticator { public PTCookieAuthenticator(Context context) { super(context, "realm-text", "my_16_bytes_text".getBytes()); } @Override protected int beforeHandle(Request request, Response response) { if (request.getResourceRef().getRemainingPart().startsWith("/loginForm")) { return CONTINUE; } else { return super.beforeHandle(request, response); } } } 2. RestletService.java public class RestletService extends Application { ... public Restlet createInboundRoot() { router.attach("/loginForm", LoginForm.class); PTCookieAuthenticator cookieAuth=new PTCookieAuthenticator(getContext()); cookieAuth.setLoginFormPath("/loginForm"); } The Pieter Martin suggested every thing, but changing the loginPath("/rest/special/loginPost") made me confusion. I thought I should do something in the post method. Thanks, Ramesh -- View this message in context: http://restlet-discuss.1400322.n2.nabble.com/How-to-use-CookieAuthenticator-tp7578835p7579062.html Sent from the Restlet Discuss mailing list archive at Nabble.com. -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3072942
Re: How to use CookieAuthenticator?
Thanks Jerome Louvel for your understanding and quick action. I have been trying last 3 days to get it work. I tried many possible ways to get it work. But still I didn't success. I guess it would be very simple implementation in the loginPost server resouce. Can you please throw some clue to get it work ? I can contribute user guide once I can setup cookie authentication. @Post public Representation post(Representation details) { Form form = new Form(details); String username = form.getFirstValue("login"); String password = form.getFirstValue("password"); String targetURI = getQueryValue("targetURI"); ..//What todo here ??? } - Ramesh -- View this message in context: http://restlet-discuss.1400322.n2.nabble.com/How-to-use-CookieAuthenticator-tp7578835p7579061.html Sent from the Restlet Discuss mailing list archive at Nabble.com. -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3072932
Re: How to use CookieAuthenticator?
Hi all, Based on this ongoing discussion, it would be clearly useful to include a CookieAuthenticator example in Restlet user guide. Added new issue. If anyone wants to contribute a Markdown page for this that would be great: https://github.com/restlet/restlet-framework-java/issues/837 Also, I've entered a RFE to include the client IP address and reduce risk of replay attacks: https://github.com/restlet/restlet-framework-java/issues/838 Best regards, Jerome 2014-02-11 2:35 GMT-08:00 Ramesh Kumar : > Pieter Martin lavabit.com> writes: > > > > > Hi, > > > > Took me a while but I did get it working, > > > > Here is what I did. > > > > In my restlet application I set up the CookieAuthenticator as follows > > > > public class CMRestletApplication extends Application {... > > > > > Hi Pieter Martin, > > Thanks for the example. > > I tried to follow it. I am stuck with the "/rest/special/loginPost" action. > > Can you please post the code for the "loginPost" request ? > > I have a > secretverifier implementation which is not called for cookie authenticator. > > Thanks, > Ramesh > > -- > > http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3072851 > -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3072865
Re: How to use CookieAuthenticator?
Pieter Martin lavabit.com> writes: > > Hi, > > Took me a while but I did get it working, > > Here is what I did. > > In my restlet application I set up the CookieAuthenticator as follows > > public class CMRestletApplication extends Application {... > Hi Pieter Martin, Thanks for the example. I tried to follow it. I am stuck with the "/rest/special/loginPost" action. Can you please post the code for the "loginPost" request ? I have a secretverifier implementation which is not called for cookie authenticator. Thanks, Ramesh -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3072851
RE: Re: Re: Re: Re: How to use CookieAuthenticator?
Ah yes, something like the client's IP address would make sense. I will have to think on what information we would like to include, but at least now I know that what I want is indeed possible :) And you are right, those 3 levels of protection should be sufficient, but I am still missing one of the levels in my implementation (client specific info). So I guess I will have to decide if I really need that, or that the other 2 levels are sufficient protection. -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3060357
Re: Re: Re: Re: How to use CookieAuthenticator?
On Fri, Jul 12, 2013 at 9:32 AM, Johanneke Lamberink wrote: > But what would I put in there? Let's call it a sessionID, regardless of > the actual content. The only way this will give the protection I need > requires some sort of state on the server, doesn't it? > You could store some information about the request that is likely to be true of subsequent legitimate requests by the same client but not of a forged one, like the client's IP address. That doesn't require state on the server. It's by no means perfect, but it would force attackers to work harder to spoof client requests. > So I guess my question is, is it possible to protect against this specific > attack while maintaining a stateless server? Or did we already forfeit that > when we started setting cookies? > Aren't these three levels of protection sufficient? - Difficulty of obtaining a valid cookie in the first place. - Difficulty of using a valid cookie before it expires. - Difficulty of spoofing client-specific info. If an attacker is able to get to a client's cookie store, is not bothered by the expiration time limit, and can make requests with ClientInfo that matches the real client, then it's highly likely that the client is already deeply compromised, so keeping track of sessions on the server side doesn't really help: The attacker could just issue its requests in a valid session. So my answer is no, I don't think you give up security in any significant way by having a stateless server. If it still bothers you, though, why not isolate a small stateful service exclusively to address authentication concerns, leaving the rest of your server stateless? --tim -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3060350
RE: Re: Re: Re: How to use CookieAuthenticator?
But what would I put in there? Let's call it a sessionID, regardless of the actual content. The only way this will give the protection I need requires some sort of state on the server, doesn't it? So I guess my question is, is it possible to protect against this specific attack while maintaining a stateless server? Or did we already forfeit that when we started setting cookies? -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3060334
Re: Re: Re: How to use CookieAuthenticator?
You can override the formatCredentials and parseCredentials methods to store custom information in the (encrypted) cookie value. On Fri, Jul 12, 2013 at 9:12 AM, Johanneke Lamberink wrote: > Thanks for the reply. Yes, treating old cookies as stale is what I do now. > I was wondering if there is another way to prevent re-use of an old cookie. > > -- > > http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3060332 > -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3060333
RE: Re: Re: How to use CookieAuthenticator?
Thanks for the reply. Yes, treating old cookies as stale is what I do now. I was wondering if there is another way to prevent re-use of an old cookie. -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3060332
Re: Re: How to use CookieAuthenticator?
You can always have the Verifier treat cookies with creation times too far in the past as stale. A legitimate client will be able to provide the credentials again; an impostor with a stolen cookie won't. --tim On Fri, Jul 12, 2013 at 6:01 AM, Johanneke Lamberink wrote: > When a user requests a logout, the 'maxAge' of the cookie is set to 0, > which will tell the browser to delete it. > > However, when a cookie was stolen, this stolen cookie still exists, and > can still be used to log in. After all, the cookie contains all the > information needed for logging in, no additional information is needed at > all. > > > But maybe I'm looking for a problem that doesn't exist? > > -- > > http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3060328 > -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3060331
RE: Re: How to use CookieAuthenticator?
When a user requests a logout, the 'maxAge' of the cookie is set to 0, which will tell the browser to delete it. However, when a cookie was stolen, this stolen cookie still exists, and can still be used to log in. After all, the cookie contains all the information needed for logging in, no additional information is needed at all. But maybe I'm looking for a problem that doesn't exist? -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3060328
Re: How to use CookieAuthenticator?
Hi, I have not looked at the code for a while but my understanding was that the cookie is invalidated when the user logs out. So it can not be reused after a logout. Cookies are (optionally) set to expire after some time of no use. Cheers Pieter On 12/07/2013 11:21, Johanneke Lamberink wrote: > Well, yes, I believe that when using HTTPS, stealing a cookie means access to > the computer. But people let other people use their computer, or your laptop > might get stolen, or you might forget to lock it when you go out for lunch. > > Because of the premise that you need physical access to the computer to steal > the cookie, you probably have bigger security problems. But I would still > like to protect against this. > > I've been thinking about including some "start-of-session-timestamp" in the > cookie, that *wouldn't* get updated on each request, and have a timelimit on > the age of that timestamp. That way, a stolen cookie could only be used a > limited amount of time. > > -- > http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3060325 > > > Your personal email. Anytime, anywhere. > Ridiculously affordable at $19.95. No contracts. > http://www.getpeek.com/lavabit.html > -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3060327
RE: Re: How to use CookieAuthenticator?
Well, yes, I believe that when using HTTPS, stealing a cookie means access to the computer. But people let other people use their computer, or your laptop might get stolen, or you might forget to lock it when you go out for lunch. Because of the premise that you need physical access to the computer to steal the cookie, you probably have bigger security problems. But I would still like to protect against this. I've been thinking about including some "start-of-session-timestamp" in the cookie, that *wouldn't* get updated on each request, and have a timelimit on the age of that timestamp. That way, a stolen cookie could only be used a limited amount of time. -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3060325
Re: How to use CookieAuthenticator?
The above is assuming that https is being used. Thanks Pieter On 12/07/2013 10:32, Pieter Martin wrote: > I would also like to know about this. > > However is stealing a cookie not the same as getting access to the users > computer? > > Cheers > Pieter > > On 12/07/2013 09:53, Johanneke Lamberink wrote: >> So, as far as I can see, the Restlet CookieAuthenticator takes care of >> session fixation by generating a new value for the cookie on every request >> (encrypting the username/password/timestamp). >> >> But what about session hijacking? If every cookie contains the username and >> password, someone who got hold of a cookie could use it to log in, right? So >> when my cookie gets stolen, it can still be used after I logged out and my >> browser deleted the cookie, because the attacker still has the cookie. >> >> I have implemented a check on the time the cookie was issued, but an >> attacker could do periodic requests t make sure his stolen cookie never gets >> old. >> >> How do I protect against this? Every blog and tutorial I find just tells me >> to put the session id in the session and discard it after logout. But I >> don't have a session to store to or discard from, because the server is >> stateless... >> >> -- >> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3060314 >> >> >> Save with Super Cheap Insurance and your premium reduces monthly! >> http://click.lavabit.com/s46kjm8zs9rqxeich1cbdc5unbm5o8qyhchpswgr4w9o9uemacfy/ >> > -- > http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3060317 > > > Your personal email. Anytime, anywhere. > Ridiculously affordable at $19.95. No contracts. > http://www.getpeek.com/lavabit.html > -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3060322
Re: How to use CookieAuthenticator?
I would also like to know about this. However is stealing a cookie not the same as getting access to the users computer? Cheers Pieter On 12/07/2013 09:53, Johanneke Lamberink wrote: > So, as far as I can see, the Restlet CookieAuthenticator takes care of > session fixation by generating a new value for the cookie on every request > (encrypting the username/password/timestamp). > > But what about session hijacking? If every cookie contains the username and > password, someone who got hold of a cookie could use it to log in, right? So > when my cookie gets stolen, it can still be used after I logged out and my > browser deleted the cookie, because the attacker still has the cookie. > > I have implemented a check on the time the cookie was issued, but an attacker > could do periodic requests t make sure his stolen cookie never gets old. > > How do I protect against this? Every blog and tutorial I find just tells me > to put the session id in the session and discard it after logout. But I don't > have a session to store to or discard from, because the server is stateless... > > -- > http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3060314 > > > Save with Super Cheap Insurance and your premium reduces monthly! > http://click.lavabit.com/s46kjm8zs9rqxeich1cbdc5unbm5o8qyhchpswgr4w9o9uemacfy/ > -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3060317
RE: Re: How to use CookieAuthenticator?
So, as far as I can see, the Restlet CookieAuthenticator takes care of session fixation by generating a new value for the cookie on every request (encrypting the username/password/timestamp). But what about session hijacking? If every cookie contains the username and password, someone who got hold of a cookie could use it to log in, right? So when my cookie gets stolen, it can still be used after I logged out and my browser deleted the cookie, because the attacker still has the cookie. I have implemented a check on the time the cookie was issued, but an attacker could do periodic requests t make sure his stolen cookie never gets old. How do I protect against this? Every blog and tutorial I find just tells me to put the session id in the session and discard it after logout. But I don't have a session to store to or discard from, because the server is stateless... -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3060314
RE: Re: How to use CookieAuthenticator?
Ok, part of my confusion was because of my inexperience with cookies. The current login flow of my application is like this: Do a POST to the loginPath(). If the credentials are valid a cookie is set, and the resource of the loginPath() returns some additional information. If the credentials are invalid, still continue to the next restlet, but set the authenticated flag to false and no cookie is set. The resource of the loginPath returns an error code. I know this is not how it is supposed to be done (should return 401), but this is what I needed for my client application. Now my client application can decide what to do. After supplying valid credentials and successfully logging in, the browser will store the cookie and automatically send it with every future request (until the cookie expires, default at the end of the browser session). Every other URI that is accessed without credentials returns a 401. @Override public void challenge(Response response, boolean stale) { if (isLoggingIn(response.getRequest(), response)) { response.setStatus(Status.SUCCESS_OK); } else { response.setStatus(Status.CLIENT_ERROR_UNAUTHORIZED); } } @Override protected int unauthenticated(Request request, Response response) { // Update the client info accordingly if (request.getClientInfo() != null) { request.getClientInfo().setAuthenticated(false); } if (response.getStatus().equals(Status.SUCCESS_OK)) { // Continue the filtering chain return CONTINUE; } else { // Stop the filtering chain return STOP; } } I'm still looking for ways to prevent session hijacking and session fixation, but for now I have working code :) On to enroling/authorizing... -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3060168
Re: How to use CookieAuthenticator?
Hi, Took me a while but I did get it working, Here is what I did. In my restlet application I set up the CookieAuthenticator as follows public class CMRestletApplication extends Application {... @Override public Restlet createInboundRoot() { Router router = new Router(getContext()); ... router.attach("/rest/modules/login/login.ftl", LoginFormServerResource.class, Template.MODE_STARTS_WITH); ... CmCookieAuthenticator authenticator = new CmCookieAuthenticator(getContext(), "My Realm", /*must be 16 bytes*/"My Server KeyXXX".getBytes()); authenticator.setLoginPath("/rest/special/loginPost"); authenticator.setLoginFormPath("/cm/rest/modules/login/login.ftl"); authenticator.setRedirectQueryName("redirectUri"); authenticator.setNext(router); MapVerifier mapVerifier = new MapVerifier(); mapVerifier.getLocalSecrets().put("chunkylover53", "pwd".toCharArray()); authenticator.setVerifier(mapVerifier); ... router.attach(mode resources); ... return authenticator; } } The login form via freemarker The authenticator is a filter so I filter all urls that need authentication. public class CmCookieAuthenticator extends CookieAuthenticator {... @Override protected int beforeHandle(Request request, Response response) { if (request.getResourceRef().getRemainingPart().startsWith("/css") || request.getResourceRef().getRemainingPart().startsWith("/rest/modules/login") || request.getResourceRef().getRemainingPart().startsWith("/jquery")) { return CONTINUE; } else { int result = super.beforeHandle(request, response); if (response.getStatus()== Status.REDIRECTION_SEE_OTHER) { return STOP; } else { return result; } } } Still need to unhardcode the verifier part, but cookie authentication slipped of the priority bus for now. As far as I understand there is nothing further to do from the client side as the browser sends the cookie details are sent through with every request. The cookie is encrypted so security seems ok. I used the default key security as defined by Restlet. Logout happens via the default /logout path as specified in the CookieAuthenticator. My menu has the following logout url. logout All this might not be exactly as intended but it works in my basic tests. Hope that helps some. Pieter On 04/07/2013 19:18, Johanneke Lamberink wrote: > So I'm trying to use the CookieAuthenticator, but there are some things > unclear to me. The documentation focuses on explaining how to do HTTP Basic > or HTTP Digest, I haven't been able to find an example of HTTP Cookie > anywhere, which is a shame :( > > I am using Restlet 2.1.2. > > Question 1 > > According to the documentation: > "public void challenge(Response response, >boolean stale) > This method should be overridden to return a login form representation. > By default, it redirects the user's browser to the getLoginFormPath() URI, > adding the URI of the target resource as a query parameter of name > getRedirectQueryName(). > In case the getLoginFormPath() is not set, it calls the parent's method." > > How do you override the implementation to return a representation? The return > type is already void. > > I now have a path in the router to a ServerResource with the uri of the login > form that 'challenge' redirects to, which returns a Representation of a Form. > Is that what is meant? Then do I have to implement GET, POST, PUT and DELETE, > or only POST, or what? > If not, how should I override 'challenge'? > > Question 2 > > And how do you handle this client side? I want to make my login form in the > same style as the rest of the site. What is the flow when I return the form > from the server side? My client is a javascript web application. > > Question 3 > > When a user is logged in, what do I send on subsequent requests? How do I > handle this in the CookieAuthenticator? The authenticate method expects a > cookie with a username and password, should I send that on every request? > What if I want to use some sort of session security token? I know the server > has no state, but I thought this is where the cookies came into play. I just > have trouble understanding how exactly. > > -- > http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3059804 > > > Your personal email. Anytime, anywhere. > Ridiculously affordable at $19.95. No contracts. > http://www.getpeek.com/lavabit.html >
How to use CookieAuthenticator?
So I'm trying to use the CookieAuthenticator, but there are some things unclear to me. The documentation focuses on explaining how to do HTTP Basic or HTTP Digest, I haven't been able to find an example of HTTP Cookie anywhere, which is a shame :( I am using Restlet 2.1.2. Question 1 According to the documentation: "public void challenge(Response response, boolean stale) This method should be overridden to return a login form representation. By default, it redirects the user's browser to the getLoginFormPath() URI, adding the URI of the target resource as a query parameter of name getRedirectQueryName(). In case the getLoginFormPath() is not set, it calls the parent's method." How do you override the implementation to return a representation? The return type is already void. I now have a path in the router to a ServerResource with the uri of the login form that 'challenge' redirects to, which returns a Representation of a Form. Is that what is meant? Then do I have to implement GET, POST, PUT and DELETE, or only POST, or what? If not, how should I override 'challenge'? Question 2 And how do you handle this client side? I want to make my login form in the same style as the rest of the site. What is the flow when I return the form from the server side? My client is a javascript web application. Question 3 When a user is logged in, what do I send on subsequent requests? How do I handle this in the CookieAuthenticator? The authenticate method expects a cookie with a username and password, should I send that on every request? What if I want to use some sort of session security token? I know the server has no state, but I thought this is where the cookies came into play. I just have trouble understanding how exactly. -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3059804