play-authenticate icon indicating copy to clipboard operation
play-authenticate copied to clipboard

Distributed application and usage of cache

Open gluk64 opened this issue 10 years ago • 12 comments

Play-authenticate seems to rely heavily on play.Cache for storing intermediate state. This won't work if my application is deployed in cloud on more than one server.

Cache could also get cleared any time...

Is there a possible workaround?

gluk64 avatar Feb 23 '14 19:02 gluk64

One possibility would be to refactor it to allow an arbitrary adapter for storing the state. The default would be the play cache, but it could be replaced with a distributed memcache/db/you name it

joscha avatar Feb 23 '14 20:02 joscha

I already started doing it by subclassing FacebookAuthProvider and overriding authenticate() method, it seems to work :) But refactoring would be a more elegant way. Should I write a patch and make a pull request?

gluk64 avatar Feb 23 '14 20:02 gluk64

yes, please :) we can make the default a config variable and you can just drop in your own. Where do you store it now? If its something generally available, we could ship that adapter as an option with PA...

joscha avatar Feb 23 '14 20:02 joscha

Ok. I'm going to store it in PostgreSQL.

gluk64 avatar Feb 23 '14 20:02 gluk64

btw, is it possible to make oauth completely stateless? one could store the secret UUIDs in the session with cryptography. I would strongly prefer this option than accessing the DB.

gluk64 avatar Feb 23 '14 20:02 gluk64

The state parameter is used to protect against CSRF attacks, so I am not sure how a state parameter coming from the user's machine will help with that, because it is inherently unsafe. The state parameter is used to make sure that the initial request made and the return callback coming back match up with each other. If you wouldn't do that (or allow the client to control the state) an attacker could technically link a different account than the one you intended to. Technically I think with Play 2.0's handling of session variables (the hashed cookie vars) and the guarantee, that they can't be tampered with, it could be possible to put the state into it and read it out upon return of the OAuth request, but googling this has not exactly convinced me this is a standard procedure - most libraries seem to take the "server-side-session-random-state-string-approach".

joscha avatar Feb 23 '14 20:02 joscha

If you program the state storage adapter flexible enough, though, it should be easy to implement this "session" approach and ask people that are more knowledgeable with the OAuth2 flowin general to verify its clean :)

joscha avatar Feb 23 '14 21:02 joscha

Let's do it. We can store only a strong hash of the state string in the cookie, it's almost as safe as holding it in secret on the server side. People entrust billions of dollars worth in the hash approach used by Bitcoin :)

gluk64 avatar Feb 23 '14 21:02 gluk64

But what is storeUserInCache() used for?

gluk64 avatar Feb 23 '14 21:02 gluk64

It's used for the linking/merging accounts capabilities of Play!Authenticate - you can disable those in the config.

On Sun, Feb 23, 2014 at 10:07 PM, gluk64 [email protected] wrote:

But what is storeUserInCache() used for?

— Reply to this email directly or view it on GitHubhttps://github.com/joscha/play-authenticate/issues/152#issuecomment-35843420 .

joscha avatar Feb 23 '14 21:02 joscha

I see that, what I don't understand is why linking and merging must rely on cache rather than on UserService?

gluk64 avatar Feb 23 '14 21:02 gluk64

at the point in time where the merge/link happens, the "new" user is not yet part of the UserService, as it is not persisted, yet, that's the whole point of linking for example - to not end up with duplicate DB entries for the same user. Linking and merging could definitely be changed to not rely on the cache, if I remember correctly, there should be TODOs in the source...

joscha avatar Feb 23 '14 21:02 joscha