Android AccountManager and dmfs/oauth2-essentials using refresh token - android

I am trying to use dmfs/oauth2-essentials for oauth2 in an application. The problem is the refresh token. I am able to store the token string and refresh token string in AccountManager. Refresh token using userdata bundle. User first logins with ResourceOwnerPasswordGrant and receives a token with refresh token.
The problem is that Bundle accepts just primitive things like strings to be stored. But the dmfs/oauth2-essentials require the OAuth2AccessToken object when using TokenRefreshGrant()
Is there a way to use the refresh token string directly? am I missing something?
Thanks!

I don't know if you've solved your problem, but I'll write here my experience in case it's handy for somebody.
You can create an Account in android using AccountManager. You're right by storing AccessToken in the Account, but perhaps you haven't realised that you can store multiple tokens within an Account, just by typing different token type. That way, you can retrieve different tokens using peekAuthToken(Account account, String authTokenType) just by passing a different authTokenType String. Be careful not letting the user to retrieve a refreshToken outside your Authenticator in getAuthToken(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle options), I do so by comparing authTokenType string.

Related

React Native: What is returned by Auth.signIn()?

I am developing using react-native with Amazon AWS as back-end. I am also using amplify library.
For logging in, I am using the below call:
const user = await Auth.signIn(...)
https://docs.amplify.aws/lib/auth/emailpassword/q/platform/js#sign-in
https://aws-amplify.github.io/amplify-js/api/classes/authclass.html#signin
My related questions:
I get a big JSON in the user variable. I believe it is the AWS credential?
The above signIn() call DOES NOT return a JWT token, it returns AWS credential. Is it? Also see the post:-
https://stackoverflow.com/a/59327655/15943787
Above post mentions:
After successfully authenticating a user, Amazon Cognito issues JSON
web tokens (JWT) that you can use to secure and authorize access to
your own APIs, or exchange for AWS credentials
What is meant by above statement? What is Auth.signIn() doing? getting JWT token or credentials?
Does this returned credential get stored inside the mobile device? By default in android it is stored un-encrypted. Right?
Is it stored in sharedPreferences?
The Auth.signIn() returns a CognitoUser Object as defined in the API Docs.
Below is from AWS SDK for Android but the data in Javascript is the same, (found here). The JWT Token in stored in the CognitoUser.CognitoUserSession attribute.
Represents a single Cognito User.
This class encapsulates all operations possible on a user and all tokens belonging to the user. The user tokens, as CognitoUserSession, are stored in SharedPreferences. Only the tokens belonging to the last successfully authenticated user are stored
So to answer your questions:
I get a big JSON in the user variable. I believe it is the AWS credential?
The user variable is a CognitoUser Object, which represents a single CognitoUser. to get the JWT token try user.sessionId or user.tokenId
The above signIn() call DOES NOT return a JWT token, it returns AWS credential. Is it? Also see the post:- https://stackoverflow.com/a/59327655/15943787
It updates the CognitoUser with session and token JWT. Check the user object to find them, after Auth.signIn() the user Object would have updated if AWS issued tokens
Does this returned credential get stored inside the mobile device? By default in android it is stored un-encrypted. Right?
Its being stores in Shared Preferences. so yes it's on device and un-encrypted. But AWS manages updating the and changing the JWT as the user interacts with cognito automatically.
Is it stored in sharedPreferences?
Yes, it is stored in sharedPreferences

Token that returned from the method getIdToken() is too long, does this correct or there is something error?

I am trying to implement Google Sign in OAuth 2.0, but I have inquiry why the token returned from the method getIdToken() is very too long such as the following:
eyJhbGciOiJSUzI1NiIsImtpZCI6ImQ1ZWViYzRjOWY5NGVkMzVhYWE5YTdiZTUyYzM0YTNmZDUwZGQ4ODkifQ.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJhdWQiOiI1NTc5ODE0OTE1NDItc3RkcGEwY3JmOWNvMXBvNW1pZW9pczEyZG1wcnJzcDQuYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJzdWIiOiIxMDM2MjY1NDEwNDQxOTYxNTY5NjEiLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiYXpwIjoiNTU3OTgxNDkxNTQyLWoxdW5zZThhbmNtY2E2NzVnaW1hbWwzaDRpYzFwMnI2LmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwiZW1haWwiOiJtYWhtb3VkLmlicmFoaW0wMTZAZ21haWwuY29tIiwiaWF0IjoxNDY1MTQxNTMwLCJleHAiOjE0NjUxNDUxMzAsIm5hbWUiOiJNYWhtb3VkIElicmFoaW0iLCJwaWN0dXJlIjoiaHR0cHM6Ly9saDQuZ29vZ2xldXNlcmNvbnRlbnQuY29tLy1PTGZKM1JKazFjYy9BQUFBQUFBQUFBSS9BQUFBQUFBQUFCNC83anpkeTZnVkdwUS9zOTYtYy9waG90by5qcGciLCJnaXZlbl9uYW1lIjoiTWFobW91ZCIsImZhbWlseV9uYW1lIjoiSWJyYWhpbSIsImxvY2FsZSI6ImVuIn0.FCsDYU7S8TEKrbm6VxBVXaJlLzrzPuXTP_z14RMIzMZohWNOpHwLYFQivkzy1mC6KJ67qECv0MI5Ap14R2vkxr7XtU9dyZH6oWBvDOgW6KYyBazEi5214Rp-uUeFXDEDFIY_mSOaS0mjlU8N9UxZfr4zIRY6R1p2JI4l1RWOb_rid8bT4gNpA6LFeop9BtmaOeSSuOfmLheqw5Uz3Ws2WCGdu857-rTZc3W5ywfbckvkZN72CRgrKUAeRbcHuGndX83NRpBFdHChXr4FIVT3tWWjiMRsCxLTvDNxXClV269IP9tXELhqNBACdPEX60hRX-DgXPSGl9SQ85IY090nuQ
Google Signin produces a compact serialized JSON Web Token (JWT, https://www.rfc-editor.org/rfc/rfc7519) to represent the authenticated user. That token is self-contained and contains information about the user in a verifiable way. You can verify that your token is a valid JWT at: http://jwt.io So yes, it is a valid token and it gets very large as more information is embedded in it.

How does Android's account manager use the stored password to retrieve an auth token?

My question is about the Android Account Manager. I'm not sure I understand the documentation below:
http://developer.android.com/reference/android/accounts/AccountManager.html
For the method:
public AccountManagerFuture getAuthToken (Account account, String authTokenType, Bundle options, Activity activity, AccountManagerCallback callback, Handler handler)
It says this:
If a previously generated auth token is cached for this account and type, then it is returned. Otherwise, if a saved password is available, it is sent to the server to generate a new auth token. Otherwise, the user is prompted to enter a password.
I don't understand how the Account Manager would do this for my account type. My assumption was that it would call a method defined in the AbstractAccountAuthenticator to do this, but I don't see any method that seems like it would re-submit a saved password.
To clarify, I was planning to save a refresh token as the 'password' for my account. I was then planning to submit the refresh token in place of a stored password in order to get a new access token.
I tried searching in GrepCode but I'm not used to the way code is presented there, or the code isn't so clear, because I'm still not sure how the Account Manager plans to 'resubmit' the stored password and if I can override that behavior so that it instead just refreshes the access token.
Any help is appreciated. I feel like I'm missing something really obvious here.
Override getAuthToken. In that override you will perform the above workflow. Saving the password is optional. If you don't want to save the password then in getAuthToken you just validate the token that is saved already. If the token is not valid you will prompt for the login or just refresh the token with some other mechanism as defined by your requirements.

Misunderstanding Oauth2 and twitter4j

There is somthing that i can't understood. I'm trying to writte a simple app in android to post twitt's into my account. I registered my app in dev.twitter. There i got an api(consumer) key/secret, and access token/access secret pairs. BUT, as in the example, i must use setOauthConsumer(cons key, cons secret) then, after that in the app I must use get getOAuthAccessToken to get oauth access token. But i'm alredy have this(!), so i can use acces token and secret directly, or what?
p. s. i know twitter4j.org examples, and i can use other resources, but i cant find the answer, so i'm posting here
i must use setOauthConsumer(cons key, cons secret) then, after that in
the app I must use get getOAuthAccessToken to get oauth access token.
But i'm alredy have this(!), so i can use acces token and secret
directly, or what?
We need the following 4 values for every request to twitter API:
Consumer key
Consumer Secret
Access Token
Access Token Secret
You already have the following values:
Consumer key
Consumer Secret
Access Token & Access Token Secret are fetched in following two ways:
Case 1: Configuration required for app-only auth, to fetch the twitter feeds even
without Logging in to twitter account.
As you have not logged in, the twitter4j gives the OAuth2Token (access token and token secret) using getOAuth2Token();
Then you use these values in your configuration of Twitter instance. No need to store these values. You can get them using getOAuth2Token() for every request.
Case 2: When you login using your credentials.
In this case, the request is sent to Twitter API to get access token and access token secret (values are generated at the time of registering your application on Twitter).
Once you get these values, store it in SharedPrefernces and use them in subsequent requests. No need to request them again and again.
I hope this helps you.

Facebook auth token exchange

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;
}

Categories

Resources