I need to make calls to services which are secured by OAuth2 resource owner password credentials. I tried all the libraries on oauth.net/code, but with no success. All of them seem not to provide this kind of authentication, but seem to be great with 3 legged authentication.
My user should login with username and password, but I do not want to store username and password. I want to get an access token and refresh this token from time to time.
My network communication is currently based on spring 4 android and the resttemplate you can find there.
Any suggestions, which library I could use? I think this is a common problem.
I couldn't find anything either, so I've put together a library myself, and I am releasing it to the public.
Usage:
import org.sdf.danielsz.OAuth2Client;
import org.sdf.danielsz.Token;
OAuth2Client client = new OAuth2Client(username, password, app-id, app-secret, site);
Token token = client.getAccessToken();
token.getResource(client, token, "/path/to/resource?name=value");
With this grant type, the client application doesn't need to store the username/password of the user. Those credentials are asked once and exchanged for an access token. This token can then be used to access protected resources.
To check if a token has expired:
token.isExpired();
To manually refresh a token:
Token newToken = token.refresh(client);
A more involved example can be found in the README on github.
Check out this url : https://temboo.com/library/Library/Fitbit/OAuth/ and https://temboo.com/library/Library/Fitbit/OAuth/InitializeOAuth/
In order to run java code to generate OAuth url, you will need temboo.jar file which you can download by clicking on java icon on right hand side link.
cheers.
Related
I've been trying to add Google Sign-In in Android but have a couple of doubts.
From the Android documentation Integrate google sign in android
In the server side authentication part Client Id is required which is OAuth 2.0 web application client ID for your backend server.
From android's documentation:
Get your backend server's OAuth 2.0 client ID
If your app authenticates with a backend server or accesses Google APIs from your backend server, you must get the OAuth 2.0 client ID that was created for your server. To find the OAuth 2.0 client ID
From my understanding the flow would be:
Android app will get the auth code from google which will be passed to the backend.
The backend will get the access token with the auth code from the android app and the client secret.
With the acess token we get the user's information and the access token is saved in the database.
My doubts are:
I read somewhere on StackOverflow that we need to create two OAuth client one for Android and one for Web Application. Is this True?
Django Rest Auth Login View need to have one redirect_url defined but I don't understand what would be the redirect_uri in case of Android device or we need to pass this URL while getting the auth code from Google.
On OAuth Playground I put my backend's client id and client secret and got the auth code and when I passed this auth code to my login view I was getting the redirect_uri_mismatch but If I put redirect_url = 'developer.google.com' It works, I guess the auth code contains host information from where it is generated that's why this should be the same as redirect_url in my rest-auth view but then for android what it should be?
Here is my Google Login View.
class GoogleLogin(SocialLoginView):
adapter_class = GoogleOAuth2Adapter
client_class = OAuth2Client
callback_url = 'localhost:8000' # What this should be?
Please ask for more information If I forgot to put any.
I am using this
django-rest-auth
Some helpful link -
https://github.com/Tivix/django-rest-auth/issues/262#issuecomment-256562095 # It says callback URL could be a fake one but I get redirect_uri_mismatch
So Finally, I figured it out, Answering my own question so someone might find this helpful.
Yes, you need two client id one for your Android device and one for your web application.
Just add http://localhost:8000/accounts/google/login/callback/ as callback_url in the GoogleLoginView and put the same in your Google developer console.
I don't know exactly if the auth code generated by the Android contains any host information or not but it seems as long as the callback URL you added in the login view class and in google developer console is the same it will work.
Your Google sign in view should look like this.
class GoogleLogin(SocialLoginView):
authentication_classes = (JSONWebTokenAuthentication,)
adapter_class = GoogleOAuth2Adapter
callback_url = 'http://localhost:8000/accounts/google/login/callback/'
client_class = OAuth2Client
Note: You only need callback_url and client_class in case where you are passing the auth code to this view but if in you are passing the access_token then callback_url and client_class is not necessary.
I am using retrofit 2.0 to build a Bitbucket REST client on Android.
As far as I'm concerned, OAUTH2.0 provides "Implicit grant" which gives the client the access Bearer token immediately when the user logins to their account when are prompted to.
Bearer tokens are tokens that can be used to access protected resource. Anyone who has a bearer token has the permission to access the protected resource as anyone else who also has the bearer token. (according to this doc from IETF)
Please correct me if I'm wrong, but I thought using implicit grant, after user logins in their Bitbucket account, I will have the Bearer access token. After that, I can use this access token to access protected resource on Bitbucket (like create a new repository).
So I have built my android using the OAUTH2.0 Implicit grant as described in the Bitbucket doc. Note that they described the response will have #access_token={token}&token_type=bearer
And this is what I actually received from Bitbucket after logging in:
your://redirecturi#access_token=lEuvneW39onVrnNR-jvZfirI43fwi5Wdc0YaaMROBk5YKJsd2ulXm20vJDdOBjf8I-Ne2r2vC8-_FHECSLw%3D&scopes=pipeline%3Awrite+webhook+snippet%3Awrite+wiki+issue%3Awrite+pullrequest%3Awrite+repository%3Adelete+repository%3Aadmin+project%3Awrite+team%3Awrite+account&expires_in=3600&token_type=bearer
My first question:
What exactly is the Bearer access token from the above response?
Is the part lEuvneW39onVrnNR-jvZfirI43fwi5Wdc0YaaMROBk5YKJsd2ulXm20vJDdOBjf8I-Ne2r2vC8-_FHECSLw the Bearer access token? Do I have to include the "%3D" (which is the char "=" encoded in ASCII)? Doesn't the Bitbucket doc mean that everything exceptfor the last "&token_type=bear" is the Bear access token?
That's not all. Bitbucket doc's instruction to make request as follow:
Send it in a request header: Authorization: Bearer {access_token}
So I set this request up to create a new repository in accordance with the API of Bitbucket:
#POST("repositories/{username}/{repo_slug}")
Call<Repository> createRepository(
#Header("Authorization") String auth,
#Path("username") String userName,
#Path("repo_slug") String repoSlug);
But everytime, I got the respones with status code 401 and message error:
Access token expired. Use your refresh token to obtain a new access token.
When I tried to POST the same request using DHC by Restlet (a chrome extention like Postman), a pop up appears and requires me to login to Bitbucket. If I refuse to do so, I got the same error 401 response. If I do login, then it works.
My second question: Why do I have to provide my credentials again?
I think there's something wrong here. I thought with the Bearer access token, I should be able to access the protected resource without having to log in before the access token's expire time has been reached. Why do I have to enter my credentials the second time? This is not what is described in the "Implicit grant" approach here by IETF.
The value of the access_token starts after access_token= and ends before the next parameter scopes so before &scopes=. The formatting of the fragment part is specified in https://www.rfc-editor.org/rfc/rfc6749#section-4.2.2 which in its turn points to https://www.w3.org/TR/1999/REC-html401-19991224/interact/forms.html#h-17.13.4.1 which says:
[...] The name is separated from the value by = and name/value pairs
are separated from each other by & [...]
So your access token value by spec is lEuvneW39onVrnNR-jvZfirI43fwi5Wdc0YaaMROBk5YKJsd2ulXm20vJDdOBjf8I-Ne2r2vC8-_FHECSLw%3D but I agree that the ending %3D is suspicious and may be an error on the sender's part.
If your access token is expired (which is what it seems to be) you need to get a new one using the Implicit grant again, or using the Refresh token grant.
Hello all i am making an android app in whiich i have multiple account login at a time now my question is that i for multiple logins i should use sessions to verify every account user that is logged in. Now i am using express on the server side i have read a lot of documentation on storing sessions in node.js
Express-session (Though it is only good for development but not for production but not for my app)
Cookie-session
connect-Redis
connect-mongo
I have also heard about json web tokens where i can generate unique tokens and then i can pass the tokens to the client using res.json({user_id:"user1", token: "generated_token here"})
I have also heard about passport but dont know how it is going to do this also as in passport i use express-session by default will it be good for production or not ??
Now my first question is i have read all of there docs and nowhere it is mentioned where i am creating unique tokens for every user that is signing up.
Second question as i am using my server for android app there will be no use of cookie i will be sending user token as in parameter req.body.token now how to cmpare this with current user_id.
Actually i dont get the flow of control i mean how everything is going on in session in node.js. Also what is this secret is this thing generating unique tokens or what. Also i mean about 100000 of users are registered for my app now please tell me accordingly which way should i use for my app.
I have asked this question previously but there i did not mention that as i am not making a website how to do this(As in my case there will be no use of tokens)
I know this question i am asking is very vague but please bear with me i just want to understand how sessions are used in node.js
Thanks Anways
I'll try to answer this, but it is vague (as you pointed out). I'm going to make an assumption that your Android app is a native Android app and is going to be connecting to some sort of NodeJS backend in the cloud that is based on ExpressJS. If that's not the case, please clarify your thoughts in an update to your question.
The best idea for this specific scenario is to look to the cloud provide. Azure App Service Mobile Apps, for example, allows you to implement authentication - it eventually returns a JSON Web Token (http://jwt.io) to authenticate each request.
If you don't want to be beholden to a cloud provider, but want to run it yourself, you are going to have to implement the token generation and checking yourself. This generally follows the form:
Set up a WebAPI endpoint (maybe /signin) which takes whatever token the identity provider gives you, verifies the information and returns a JWT - there is an NPM module (jsonwebtoken) for producing the JWT. Ensure the JWT includes the identity of your user. I tend to use email address for the identity.
Your Android application will do a WebAPI request to your backend with an Authorization header, the value of which is "Bearer "
Your NodeJS API will use JWT authorization to validate the JWT and extract the user identity so you can use it in your API logic.
The important thing to note in this specific scenario is that your backend code is implementing a WebAPI - there are no cookies nor sessions in the API. The only thing that is linking the user from the client code to the backend code is the JWT.
As a short piece of code, here is how you verify a JWT:
var express = require('express');
var app = express();
var jwt = require('express-jwt');
var jwtCheck = jwt({
secret: new Buffer('your-jwt-secret', 'base64'),
audience: 'your-jwt-audience'
});
app.get('/api/protected', jwtCheck, (req, res) => {
// Your code here
});
app.listen(process.env.PORT || 3000);
I'm trying to authenticate a mobile application for the Android platform to a custom node.js server api. I would like to use Google OAuth2 tokens for this rather than roll my own authentication, since Android devices with Google Play installed make this available to app developers. I'm using the GoogleAuthUtil.getToken call from the Google Play Services library, documented here. I'm trying to follow the advice outlinedin this android developers blogpost
The getToken method is returning in my case a long 857 byte string. If I try to pass this token to Google's TokenInfo endpoint, it returns:
{'error': 'invalid_token', 'error_description': 'Invalid Value'}
What am I doing wrong here? In the 'scope' of the getToken call, I am sending:
audience:server:client_id:**i_put_my_clientid_here**. I have a clientid generated for "installed applications". Using this client id, the call to getToken doesn't work at all. When I generated a client id for a "service account", the call succeeds, but I get an 857 byte token that fails when passed to the TokenInfo endpoint as described above.
EDIT:
I also created a client id for "web applications", as it appears that is the right client id to use when calling getToken. But the behavior is the same, I get back an 857 byte token that doesn't validate when calling Google's endpoint.
How can I properly get a valid auth token using Google Play services on Android? Once I have the right token, what is the right node.js library to validate it server side? Can I use passport-google-oauth ?
Hm, this is really a comment rather than an answer, but I can’t put newlines in those:
it has to be the web-side Clent ID that goes in the put_my_clientid_here spot
if GoogleAuthUtil.getToken() gives you a String withou throwing an Exception, it really ought to be valid. When you hit tokeninfo, did you use ...tokeninfo?id_token=<857-byte-value-here>
if you’re a rubyist, grab the google-id-token gem and see if it can validate your 857-byte token.
If you just want to read the contents of the data returned by GoogleAuthUtil.getToken then the process is very simple. The returned data is simply a JWT. So all you'd have to do is split the data by the . character, and then base64 (url) decode each piece.
It gets slightly more complicated if you want you want to verify the message's authenticity. Simply use your favorite crypto library to do the verification. The 3rd component of the JWT is the signature of the data and the Google certs are publicly available; that's all you need to verify the message.
For a week I have been looking into how to validate GoogleAuthUtil tokens received in Android Client application at Node.js server using passport.js
Finally I came across passport-google-token passport strategy which perfectly performs the task.
https://www.npmjs.com/package/passport-google-token
More details are present in the above link.
The official node SDK lets you do that now.
Here's the link: https://github.com/google/google-auth-library-nodejs/blob/master/lib/auth/oauth2client.js#L384
I'm not too familiar with the details of how Android works with respect to handing a token from the device to the server. My general impression, however, is that you don't go through the typical web-based OAuth dance. Instead, you directly call the "user info" endpoint, which will return the info corresponding to the user who holds the token, or reject the request if the token is invalid. There's some discussion on this related question:
validating Android's authToken on third party server
In effect, the token becomes a secret that is shared between both the device and your server, so its important to protect it.
There are a couple strategies for Facebook and Twitter that were developed to do similar things using tokens from iOS devices:
https://github.com/drudge/passport-twitter-token
https://github.com/drudge/passport-facebook-token
You can take some inspiration from them and tweak it to talk to Google's endpoints. Let me know how this turns out. I'd love to see a similar "passport-google-token" strategy, so if you implement one, let me know and I'll link to it!
Is it possible to authenticate the user on server side using auth token retrieved by Android applicaton from Facebook?
In other words Android application uses SSO and obtain auth token. Then sends this token to backend application deployed on Google App Engine. Then backend application verifies the user against Facebook using the token.
I guess it's not feasible because retrieved token can be used only by Android application, but who knows? Maybe it may be reused somehow?
The Token you get from Android API can be sent to your server, who can check the validity of the token by querying the graph ( using /me?auth_token=.... for example).
The problem is that the same token can be used by any third party - it's not client specific - and so if you base server identification based on that, you have a problem (since a third app could use its user token and get authenticated by you). I am trying to find a way to solve this issue, but I don't have good ideas yet...
Facebook actually has an Android SDK that lets you do this. Information can be found here.
Yes you can. A valid access token is a valid access token. The Graph API does from where the token came, but only that the token has the appropriate permissions to access that portion of the graph api. Keep in mind, though, that the token is only valid for 24 hours from the time of its issuance. (is that really a word?) From the time it is issued?
When using facebook android sdk with SingleSignOn (SSO), the access token format actually changed.
Instead of getting traditional auth token which contains userid & session key as a part of authToken
now we get a different format of authToken
As Facebook Devs are still in process to support there rest apis with newly formated access token
meanwhile we can disable the SSO on android facebook sdk by changing DEFAULT_AUTH_ACTIVITY_CODE to -1 from 32665 (in Facebook.java)
This will invoke Traditional dialouge for granting acess token and in return you'll get access token which will contain session key in it.
Those who are looking for generating secure session key you need to add your own method in Facebook.java like
public String getSessionSecret(String accessToken) throws MalformedURLException, IOException
{
Bundle b = new Bundle();
b.putString("method", "auth.promoteSession");
b.putString("access_token", accessToken);
b.putString("session_key_only", "true");
String response = request(b);
return response;
}