joscha / play-authenticate

An authentication plugin for Play Framework 2.x (Java)
http://joscha.github.com/play-authenticate/
Other
807 stars 366 forks source link

Distributed application and usage of cache #152

Open gluk64 opened 10 years ago

gluk64 commented 10 years ago

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?

joscha commented 10 years ago

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

gluk64 commented 10 years ago

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?

joscha commented 10 years ago

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...

gluk64 commented 10 years ago

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

gluk64 commented 10 years ago

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.

joscha commented 10 years ago

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 commented 10 years ago

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 :)

gluk64 commented 10 years ago

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 commented 10 years ago

But what is storeUserInCache() used for?

joscha commented 10 years ago

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 notifications@github.com 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 .

gluk64 commented 10 years ago

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

joscha commented 10 years ago

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...