Question

I have read a lot of tutorials on Sync Adapter such as the tutorial on http://www.c99.org/2010/01/23/writing-an-android-sync-provider-part-1 as well as the SampleSyncAdapter sample code on Android Developer website. But I don't understand that how the server side handles the Authentication and synchronization queries. Is it possible for me to use php to query from a mySQL server database?

Was it helpful?

Solution

The piece you're missing is not part of a Sync Adapter. It's the AbstractAccountAuthenticator. It's the class that actually deals with the user's password, and passing it to the server, and it will need to be written in a manner that's well paired with the server in question.

How:

First off, how does the process work?

  1. User enters username and password on the Settings->Accounts and Sync page.
  2. (Later...) Sync process starts.
  3. SyncAdapter calls blockingGetAuthToken()
  4. AccountAuthenticator starts.
  5. AccountAuthenticator uses regular http (or ideally, https) authentication to connect to the server, and once authenticated, requests a 'token' from the sever. This token is a large (say, 128 bit) random number, should only be able to be obtained from the server if you've logged in using password based authentication.
  6. AccountAutenticator caches the token, and then returns the token to the SyncAdapter.
  7. SyncAdapter tries to access content on the server, and passes the token as part of the http headers in its requests.
  8. Server accepts the token in lieu of normal http-auth, and allows the request to be served.
  9. Future sync attempts will end up skipping much of this process. On the following sync attempts, when the SyncAdapter calls blockingGetAuthToken(), the AccountAuthenticator simply returns the cached token, not needing to re-authenticate.

So this token is limited use -- After a while, the server will refuse to accept it. At that point, the SyncAdapter tries to use the token and gets an authentication error. So then what?

  1. The SyncAdapter calls invalidateToken(token) and passes the (now expired token) back to the AccountAuthenticator.
  2. AccountAuthenticator finds the token in its cache and throws it away.
  3. On the next call to blockingGetAuthToken(), the AccountAuthenticator will go communicate with the server and get a new token. From there, sync proceeds normally.

Why?

So there are several advantages.

  1. Normal http auth transmits the password in plaintext over the internet. If tokens are used, the password is sent only once, the token many times. This somewhat reduces the exposire of the password to sniffing.
  2. https authentication avoids the plaintext problem, but can be expensive, in terms of a mobile connection. Use of tokens allows lighter-weight http connections for the server calls that actually carry data, the https overhead is only seen on the first request, when the token is obtained.
  3. Segregation -- An AccountAuthenticator knows the user's actual pasword. The SyncAdapter only gets access to the the token and never learns the password. This is important to, say Google, because it allows a third party app to use a gmail account and pasword to authenticate, without the third party app (which could be malicious) to get the pasword (and forward it to a devious naer-do-well)

Expiration:

Tokens are kind of dangerous. Anyone who gets access to the token can login as you. So, good practices here:

  1. The server should expire a user's tokens after a fixed period of time. More paranoia -- shorter timeouts.
  2. The server should expire all a user's tokens whenever the user changes their password.
  3. The server should probably not expire a token assigned to a web device if the user on a web interface logs out. There isn't really a 'logout' concept for tokens.
  4. The server should consider tying a token to the IP address that first requests it, and then refuse authentication (but not necessarily expire) the token if a different IP address subsequently tries to use that token. If you do this, the server will definitely need to be capable of creating multiple tokens per user (one token per user:ipaddress combination) -- consider a user with two mobile devices -- without that, each time one syncs, it would invalidate the other's token. Consider also, two devices both on home wifi (sharing one ip address behind a router, and then one device leaves and starts using mobile network -- That's why you might choose not to expire, so the device still sitting at home can continue to use the token. However, the one device that goes roaming will see an auth failure and establish its own new token. When it comes home, the server should be sure to provide the same token that's already established for that IP address.)
  5. Depending on your paranoia level, consider only accepting auth tokens over https anyway. Firesheep is a great example of what a stolen Auth Token can get you. If you have user-sensitive data, you should only accept over https. Also, even if you don't have user-sensitive data, you might consider writing a protocol that demands https to change the DB while allowing http to read.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top