Android - Scope for access gmail with server - android

I want to connect with oAuth2 the IMAP of Google. But the App seems to be not really authorize.
I try using the scope oauth2:https://mail.google.com/ but the token returned is unusable by the server.
Then I want to set more datas on the scope Android say : "INVALID_SCOPE".
The scope is:
String scope = String.format("oauth2:server:%s:client_id:%s:api_scope:%s",
API_KEY, CLIENT_ID, "https://mail.google.com/");
With:
API KEY: the API KEY of the Server Application (not the web Application Client Api Key)
CLIENT_ID: The Client ID of the Service Account (not the web application)
The full Code is :
public static String getToken(final Context context, final Activity activity, final String accountName)
{
AsyncTask<Void, Void, String> task = new AsyncTask<Void, Void, String>()
{
#Override
protected String doInBackground(Void... params)
{
String token = null;
try
{
String scope = String.format("oauth2:server:%s:client_id:%s:api_scope:%s", API_KEY, CLIENT_ID, "https://mail.google.com/");
Log.i("GooglePlusSignupTool", "scope : "+scope);
token = GoogleAuthUtil.getToken(context, accountName, scope);
}
catch (IOException transientEx)
{
// Network or server error, try later
Log.e("GoogleSignupTool", transientEx.toString());
}
catch (UserRecoverableAuthException e)
{
// Recover (with e.getIntent())
Log.e("GoogleSignupTool", e.toString());
Intent recover = e.getIntent();
context.startActivity(recover);//ForResult(recover, REQUEST_CODE_TOKEN_AUTH);
}
catch (GoogleAuthException authEx)
{
// The call is not ever expected to succeed
// assuming you have already verified that
// Google Play services is installed.
Log.e("GoogleSignupTool", authEx.toString());
}
return token;
}
#Override
protected void onPostExecute(String token)
{
Log.i("GoogleSignupTool", "Access token retrieved:" + token);
}
};
task.execute();
Log.i("GoogleSignupTool", "END");
return "";
}

Related

android getAuthToken hang after authToken reset

Im having problem on getAuthToken() provided in android AccountManager where (steps as below):
after resetting the authToken to null (in logout process)
invalidate the new null authToken
set new authToken to new string provided by server (login back)
invalidate the new string authToken
and try to check/get on the new authToken,
but on getting the new authToken via getAuthToken() method, the call
future.getResult() hangs forever. this doesnt happen on first time login *during account creation. i able to get the auth token using the same callable class.
Below are my defined callable class. please advice on how to solve this matter.
private AccountManagerFuture<Bundle> future = null;
private String authToken;
class GetAuthTokenTask implements Callable<Bundle> {
private AccountManager accountManager;
private Account account;
private String authType;
private Activity activity;
public GetAuthTokenTask(AccountManager accountManager, Account account, String authType, Activity activity) {
this.accountManager = accountManager;
this.account = account;
this.authType = authType;
this.activity = activity;
}
/**
* Computes a result, or throws an exception if unable to do so.
*
* #return computed result
* #throws Exception if unable to compute a result
*/
#Override
public Bundle call() throws Exception {
return getAuthToken();
}
private Bundle getAuthToken() {
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
future = accountManager.getAuthToken(account, authType, null, activity, null, null);
try {
Bundle result = future.getResult();
if (result!=null) {
authToken = result.getString(AccountManager.KEY_AUTHTOKEN);
}
} catch (OperationCanceledException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (AuthenticatorException e) {
e.printStackTrace();
}
Bundle output = new Bundle();
output.putString(AccountManager.KEY_AUTHTOKEN, authToken );
return output;
}
}
//caller method
private String getAuthToken(Account account, String authType) {
ExecutorService es = Executors.newSingleThreadExecutor();
GetAuthTokenTask authTokenTask = new GetAuthTokenTask(accountManager, account, authType, (Activity)getBaseContext());
FutureTask<Bundle> result = new FutureTask<Bundle>(authTokenTask);
es.execute(result);
Bundle resultBundle = new Bundle();
try {
resultBundle = result.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
return resultBundle.getString(AccountManager.KEY_AUTHTOKEN);
}
try to avoid use of activity like this
future = accountManager.getAuthToken(account, authType, null, true, null, null);

Twitter OAuth issue: error 401

i am trying to get twitter work.
Error which i receive is:
Authorization failed (server replied with a 401). This can happen if the consumer key was not correct or the signatures did not match
I have already checked a lot of same issues here, on stackoverflow and here what i already tried:
1) checked consumer key (it is the same with that on dev.twitter.com)
2) added Callback URL for my app on dev.twitter.com
3) updated library to twitter-4j-core-3.0.5.jar
4) checked if time of my tablet is correct (set Eastern European Time)
Also i must say that some month ago Twitter in application worked properly. Then somehow it broke down.
Here is my code:
class GetOAuthVerifierTask extends AsyncTask<Void, Void, String> {
private Context context;
public GetOAuthVerifierTask(Context context) {
this.context = context;
dialog = ProgressDialog.show(TwitterActivity.this, getString(CANNOT_GET_REQUEST_TOKEN), null);
}
#Override
protected String doInBackground(Void... params) {
TwitterUtils twitterUtils = TwitterUtils.getInstance();
OAuthConsumer consumer = twitterUtils.createConsumer();
OAuthProvider provider = twitterUtils.createProvider();
try {
final String url = provider.retrieveRequestToken(consumer,
twitterUtils.getCallbackURL(context));
twitterUtils.setConsumerToken(context, consumer.getToken());
twitterUtils.setConsumerSekretToken(context, consumer.getTokenSecret());
return url;
} catch (Exception e) {
Logger.debug("Can not retrieve request token");
Logger.error(e.getMessage(), e);
return null;
}
}
#Override
protected void onPostExecute(String url) {
dialog.dismiss();
if (url != null){
// HERE IT WORKS CORRECT
web.loadUrl(url);
}
else{
Toast.makeText(TwitterActivity.this, getString(DOWNLOAD_WAIT_MESSAGE),
Toast.LENGTH_LONG).show();
}
}
}
class GetAccessTokenTask extends AsyncTask<Uri, Void, Boolean> {
#Override
protected void onPreExecute() {
dialog = ProgressDialog.show(TwitterActivity.this, getString(CANNOT_GET_REQUEST_TOKEN), null);
}
#Override
protected Boolean doInBackground(Uri... params) {
TwitterUtils twitterUtils = TwitterUtils.getInstance();
String oauthVerifier = params[0].getQueryParameter(OAuth.OAUTH_VERIFIER);
OAuthConsumer consumer = twitterUtils.createConsumer();
consumer.setTokenWithSecret(twitterUtils.getConsumerToken(TwitterActivity.this),
twitterUtils.getConsumerSekretToken(TwitterActivity.this));
OAuthProvider provider = twitterUtils.createProvider();
try {
provider.retrieveAccessToken(consumer, oauthVerifier);
twitterUtils.setAccessToken(TwitterActivity.this, consumer.getToken());
twitterUtils.setAccessTokenSecret(TwitterActivity.this, consumer.getTokenSecret());
} catch (Exception e) {
Logger.debug("Can not retrieve access token");
Logger.error(e.getMessage(), e);
return false;
}
return true;
}
#Override
protected void onPostExecute(Boolean result) {
dialog.dismiss();
if (result) {
TwitterActivity.this.sendMessage();
TwitterActivity.this.finish();
} else {
// HERE I GET 401
Toast.makeText(TwitterActivity.this, getString(DOWNLOAD_WAIT_MESSAGE),
Toast.LENGTH_LONG).show();
}
}
}
Just found the solution:
i added line
provider.setOAuth10a(true); (for my OAuthProvider)
The explanation was found in source code:
// 1.0a expects the callback to be sent while getting the request token.
// 1.0 service providers would simply ignore this parameter.
In the last month, has been a change to the Twitter API. You can now only call it using HTTPS.
You should ensure that the URL you / your library is using starts with
https://api.twitter.com/1.1/
(Notice the extra s after the http.)
You may need to check with the maintainer of twitter4j.

.GoogleAuthException: Unknown while doing Google SSO.

Exception:
07-28 14:36:13.140: W/System.err(11382): com.google.android.gms.auth.GoogleAuthException: Unknown
07-28 14:36:13.140: W/System.err(11382): at com.google.android.gms.auth.GoogleAuthUtil.getToken(Unknown Source)
07-28 14:36:13.140: W/System.err(11382): at com.google.android.gms.auth.GoogleAuthUtil.getToken(Unknown Source)
07-28 14:36:13.148: E/AndroidRuntime(11382): FATAL EXCEPTION: main
My Sign Up code:
public class Signup extends Activity {
final private String CLIENT_ID = <android-client-id>;
final private List<String> SCOPES = Arrays.asList(new String[]{
"https://www.googleapis.com/auth/plus.login"
});
private String webId = <web-client-id>;
private GoogleAccountCredential mCredential;
private EditText mExchangeCodeEditText;
private EditText mIdTokenEditText;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_google);
//mExchangeCodeEditText = (EditText) findViewById(R.id.editTextExchangeCode);
// mIdTokenEditText = (EditText) findViewById(R.id.editTextIdToken);
// initiate a credential object with drive and plus.login scopes
// cross identity is only available for tokens retrieved with plus.login
mCredential = GoogleAccountCredential.usingOAuth2(this, Arrays.asList(SCOPES.get(0)));
// user needs to select an account, start account picker
startActivityForResult(
mCredential.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER);
}
/**
* Handles the callbacks from result returning
* account picker and permission requester activities.
*/
#Override
protected void onActivityResult(
final int requestCode, final int resultCode, final Intent data) {
switch (requestCode) {
// user has returned back from the account picker,
// initiate the rest of the flow with the account he/she has chosen.
case REQUEST_ACCOUNT_PICKER:
String accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
if (accountName != null) {
mCredential.setSelectedAccountName(accountName);
new RetrieveExchangeCodeAsyncTask().execute();
new RetrieveJwtAsyncTask().execute();
}
break;
// user has returned back from the permissions screen,
// if he/she has given enough permissions, retry the the request.
case REQUEST_AUTHORIZATION:
if (resultCode == Activity.RESULT_OK) {
// replay the same operations
new RetrieveExchangeCodeAsyncTask().execute();
new RetrieveJwtAsyncTask().execute();
}
break;
}
}
/**
* Retrieves the exchange code to be sent to the
* server-side component of the app.
*/
public class RetrieveExchangeCodeAsyncTask
extends AsyncTask<Void, Boolean, String> {
#Override
protected String doInBackground(Void... params) {
String scope = String.format("oauth2:server:client_id:%s:api_scope:%s",
CLIENT_ID, TextUtils.join(" ", SCOPES));
try {
GoogleAccountCredential.usingAudience(Signup.this, "server:client_id:" + webId);
return GoogleAuthUtil.getToken(
Signup.this, mCredential.getSelectedAccountName(), scope);
} catch (UserRecoverableAuthException e) {
startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION);
} catch (Exception e) {
e.printStackTrace(); // TODO: handle the exception
}
return null;
}
#Override
protected void onPostExecute(String code) {
// exchange code with server-side to retrieve an additional
// access token on the server-side.
// mExchangeCodeEditText.setText(code);
Log.d("code",code);
}
}
/**
* Retrieves a JWT to identify the user without the
* regular client-side authorization flow. The jwt payload needs to be
* sent to the server-side component.
*/
public class RetrieveJwtAsyncTask
extends AsyncTask<Void, Boolean, String> {
#Override
protected String doInBackground(Void... params) {
String scope = "audience:server:client_id:" + CLIENT_ID;
try {
return GoogleAuthUtil.getToken(
Signup.this, mCredential.getSelectedAccountName(), scope);
} catch(UserRecoverableAuthIOException e) {
startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION);
} catch (Exception e) {
e.printStackTrace(); // TODO: handle the exception
}
return null;
}
#Override
protected void onPostExecute(String idToken) {
// exchange encrypted idToken with server-side to identify the user
// mIdTokenEditText.setText(idToken);
Log.d("idtoken",idToken);
}
}
private static final int REQUEST_ACCOUNT_PICKER = 100;
private static final int REQUEST_AUTHORIZATION = 200;
}
I'm completely clueless what's happening here. Help?
I had similar problem. In my case the problem was in missed application name in google console.
Open console navigate to your project and choose "Consent screen". Fill in the "PRODUCT NAME" field and save.
Similar to CheatEx, I had to select my email address from the "Consent Screen" page and save.

OAuth token with Google Play Game Services

Is there a way to get the token that was used to log in the user with Google Play Game Services?
I'm looking for something like:
#Override
public void onSignInSucceeded() {
String email = getGamesClient().getCurrentAccountName();
String token = getGamesClient().getToken();
}
I need this to authenticate the user when they are contacting my own server.
This is how I managed to get the token:
#Override
public void onSignInSucceeded() {
String email = getGamesClient().getCurrentAccountName();
String scopes = getScopes();
new registerBackground(getApplicationContext()).execute(email, scopes);
}
private class registerBackground extends AsyncTask<String, Void, Void> {
Context context;
registerBackground (Context context) {
this.context = context;
}
#Override
protected Void doInBackground(String... params) {
try {
String oAuthToken = GoogleAuthUtil.getToken(context, params[0], params[1]);
...
catch (Exception e) {
e.printStackTrace();
}
}
...
}

Importing gmail contacts using GoogleAuthUtil

I'm trying to add import contacts from gmail account function in my android app. So the first problem is to get access token from gmail. I've found that there is GoogleAuthUtil class which can help me with it.
Here is my code:
private void importContactsFromGmail() {
showProgressDialog();
GetTokenTask getTokenTask = new GetTokenTask();
getTokenTask.execute();
String token = "";
try {
token = getTokenTask.get();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(token);
hideProgressDialog();
}
private class GetTokenTask extends AsyncTask<Void, Void, String> {
#Override
protected String doInBackground(Void... params) {
String token = "";
try {
token = GoogleAuthUtil.getToken(activity, <My_gmail_account>, "https://www.google.com/m8/feeds/");
} catch (Exception e) {
e.printStackTrace();
}
return token;
}
}
Now after calling GoogleAuthUtil.getToken my app completely freezes(no errors in Logcat). I completely stuck and I need your help.
What is wrong with my code? Maybe I should import contacts in some other way?
Not sure if this is related but calling the .get() method on the main thread is not correct because is blocking method.
What if you use the AsyncTask in this way?
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new GetTokenTask().execute();
}
static class GetTokenTask extends AsyncTask<Void, Void, String> {
#Override
protected String doInBackground(Void... unused) {
String token = "";
try {
token = GoogleAuthUtil.getToken(activity, <My_gmail_account>, "https://www.google.com/m8/feeds/");
} catch (Exception e) {
e.printStackTrace();
}
return token;
}
#Override
protected void onPostExecute(String token) {
Toast.makeText(MainActivity.this, token, Toast.LENGTH_SHORT).show();
}
}
}
(I wrote without compiling it, maybe it needs to be adjusted)
On Android devices, Gmail contacts are synced locally onto the device and are available via a public Contacts Provider, therefore there's no reason you'd need to use the Google API to pull what is already available. There is a whole training series dedicated specifically to retrieving a list of contacts.
Note that the Contacts training series does assume you have knowledge of Content Providers already, so it may be helpful to read up on the basics of Content Providers as well.

Categories

Resources