I'm developing an Android app. I have used firebase(email, password) authentication mechanism which is very secure and easy to implement. And as I want the data to be stored in our servers, I'm not using firebase storage. Couchbase sync gateway supports any open ID authentication. But I'm finding difficult integrating both. I have been searching more than a week. Anyone who have already used it. Could you please help me configuring.
For anyone looking for an answer, here are the steps to do it:
Firebase sends you an id_token (not signed). I assume you got to this part.
You convert this unsigned firebase id_token to a signed 3rd party oidc id_token. I use Keycloak running lightweight in a docker container for this job. Remember, you want the id_token, not access_token.
(Optional) you use Sync Gateway (SGW) ADMIN REST end point to create an user and assign the user to his/her appropriate [admin_channels].
SGW will accept your Keycloak signed oidc and give you a cookie when you hit its REST interface at the /_session end point. Make sure you put the id_token string in the Authorization header in the format "Bearer id_token_string........".
A few notes:
SGW will use the username (or create a new one if none existed) based on the "username_claim" keyword definition in your SGW.json config file. Use Keycloak client's mappers function if you want to customize your SGW user's name.
If you want to get the user's id_token without having to know the user's password then use the experimental token-exchange feature as mentioned here. enter link description here.
You use this cookie information to connect and sync data with couchbase via SGW as usual.
Couchbase has an article on how to implement implicit flow for oidc using syncgateway source
Related
I'm using couchbase lite in an android app with sync gateway and couchbase in the server and it works great.
Now I want to make a request to node.js from the android app, and i want to use the same session to authorize the user in the node.js app.
Is it possible?
Can I read the session in node and match it with couchbase?
You're asking about authorization. This is tied to authentication, but you should make sure to distinguish between the two. It sounds like what you want is to authenticate the user, then have your node piece authorize access based on this.
Having said that, it depends some on the type of authentication you're using to establish your session.
Basic Authentication (when used directly with Sync Gateway) just passes a username and password that gets checked. I think you get a session cookie after that. It would be very difficult to use that to authenticate to anything else (as in, you'd have to modify Sync Gateway code yourself).
OpenID Connect, in the auth flow, might give a few ways to possibly do this.
One simpler way is to have the node app also authenticate the user. If this flowed through the same browser, the browser will often keep state that would allow the user to bypass re-authenticating. This could be a little clunky, because you'd have to pass things off to a browser (or a webview, but there are security issues with that, too), which the user would likely notice.
Another approach would be to be to do a sort of double redirect. (I think this would work, but I haven't tried it. I can't find documentation on whether an authorization code can be used twice.) In the authorization flow, have the redirect go to the node app. Then have the node app redirect again to Sync Gateway. Both apps can ask for the ID token.
Yet another way would be to have your Android app ask for the ID token directly and pass this in some protected way to your node app. As always, you'd have to protect against replay attacks, and I'm not sure what else, so this could be challenging.
In any case, Sync Gateway is built to request the ID token itself, so any approach will need to ask for the ID token twice.
Here are some references you can look at to investigate this further yourself.
http://connect2id.com/learn/openid-connect - A nice write-up of the OpenID Connect protocol.
https://developers.google.com/identity/protocols/CrossClientAuth - Google Identity Provider documentation that addresses sharing authorization between a mobile app and a web app.
http://www.thread-safe.com/2012/01/problem-with-oauth-for-authentication.html - A post describing the distinction between authentication and authorization, and why OpenID Connect (not OAuth) should be used when needing authentication.
Note: You can't use the Couchbase Node.js SDK on the bucket that is used by Sync Gateway otherwise it will mess up with the _sync metadata and documents won't sync properly; but you can query documents, create sessions, etc. using the Sync Gateway REST API.
You can refer to the documentation of the Sync Gateway REST API to get the list of available endpoints. And if you don't want to roll out your own HTTP wrapper, a JS library is available that runs on Node.js and in the browser: http://developer.couchbase.com/documentation/mobile/1.3/develop/guides/sync-gateway/rest-api-client/index.html.
I have an android app with login, registration and medical data, which connect to sails.js app to upload the data. In sails app, i have models, 'Patient',etc. Basically the android app use GET and POST json to create and get the patients in sails app. the problem is that i dont have any security, every can send a POST to create a Pacient. So the question is how i can resolve the security problem, the android app should authenticate in the sails app and then can create and get Patient and upload the medical data.
i read that some people use socket.io, is the best way?
Using websockets won't change anything about authorization. You could use JWT for this. Here is an implementation of JWT for node.js.
When a user login, generate a JWT for him. Then pass this JWT in the header of all the client's requests. Finally create a sails policy to check the JWT and allow access or not to controllers.
why not just use passport.js in the backend?
you will have to create a user model, then add few methods to your rest api to create user/login etc and off you go.
sailsjs docs itself recommends this - http://sailsjs.org/documentation/concepts/policies/sails-passport and provide link with a sample implementation - http://www.geektantra.com/2013/08/implement-passport-js-authentication-with-sails-js/.
I am having trouble wrapping my head around the following:
Android app with a Facebook login
NodeJS (Hapi.js) server backend
In the past I was using a simple username password system that made it very easy to create a server side session and authenticate server requests (for example: get all users that are within 50 km of me). I removed that system and chose for a Facebook login in the android app because it will help decrease some of the load (for example: we don't need to store our own images...).
The problem is that I am not sure how to handle server side authentication. All GET's, POST's,... can only be done by users that are also logging in on my Android app using the Facebook integration.
I found the following topics already on Stackoverflow:
Facebook authentication to my server using Android
Provide secure Facebook authentication with my Server
I just want an updated opinion on the matter, is it secure enough to just send the token to my node server and make a Facebook API call using it to check for a valid authentication?
If there is a better approach please share it! Thanks in advance.
Yes, it is secure enough to send Access Token to your server and make an API call to Facebook for validating that Access Token. AFIK this is the Best approach.
What I am planning to do:
Authenticate user using FB/Google on the client side(on the phone)
Pass the authentication confirmation to the server
Create another token to use for future communication with app
So I would write a "login" app that will create this token and that's it.
My problem:
Since all the data is mapped to UserID, how do I map the token to the user ID?
Do I write a Django middleware that does this conversion?
Do I store current_token in the User object
Do I store a map of token -> userId and use this when generating data that templates will use?
or
Do I store the user_id locally and pass it along with the token?
What I am planning to do:
Authenticate user using FB/Google on the client side(on the phone)
Pass the authentication confirmation to the server
Create another token to use for future communication with app
You never, ever, do user validation on the client side.
Social validation also happens through the server-side using the API of the openID provider (in this case, Google/Facebook).
What you are going to do is to use one of these 4 found here:
https://hackerluddite.wordpress.com/2011/05/17/review-of-4-django-social-auth-apps/
Test each of them out, see which 1 fits your needs.
What you aren't going to do is to build out your own social registration tool.
The biggest reason being that is has already been built and tested for you, so you don't need to reinvent the wheel, unless you are doing so for the sake of learning.
Security is also important, and you can consider your own solution to be less secure than a tested version.
New to OAuth2. I am writing an Android app that communicates with an App engine server application.
The app needs to authenticate itself with the server on behalf of the user, using Google account info of the user. The server needs to retrieve the user's basic info and create an account . That's the easy part and I know how to do this.
Furthermore, the Android app will also have the user authenticate himself/herself using Oauth2 and retrieve basic user info using Google account info of the user. I can do this as well.
This is where I need help Assuming the previous steps have been completed successfully, how can I use the Android app (where the user has logged in) to communicate with the server securely using the user's credentials.
Any ideas or am I missing something obvious?
The Android to App Engine OAuth2 communication is documented in this answer:
google app engine oauth2 provider
Using OAuth, 1.0 or 2.0, doesn’t matter in this, leads to the app obtaining an access token - then based on the API of your server, you pass this access token with requests instead of login and password. I guess the way to attach the access token string to URL requests may be slightly different between different APIs, see the documentation for yourself. Or if you are making the server app at the same time, then you need to figure out your way to do so (like sending a HTTP header Authorization: OAuth access_token=abcdefgh….