Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UNREGISTERED_ON_API_CONSOLE while getting OAuth2 token on Android

We're under Android (Jellybean and higher), and we've got an app which need to use OAuth2 with Google for authentication.

I simplified the login activity, but it's looking like that:

AccountManager mAccountManager;
// [...]
Account account = new Account("[email protected]", "com.google");
// same with professional email managed by Google as [email protected]
// real code recovers accounts with mAccountManager.getAccountsByType("com.google")
mAccountManager = AccountManager.get(getBaseContext());
mAccountManager.getAuthToken(account, "oauth2:https://www.googleapis.com/auth/userinfo.email", null, MyActivity.this, new AccountManagerCallback<Bundle>() {
    @Override
    public void run(AccountManagerFuture<Bundle> accountManagerFuture) {
        try {
            String token = accountManagerFuture.getResult().getString(AccountManager.KEY_AUTHTOKEN);
            // exception occurs here
            // [...]
        } catch (Exception e) {
            Log.e("account", "exception occurs", e);
        }
    }
}, null);

When we call accountManagerFuture.getResult(), it fires this exception:

android.accounts.AuthenticatorException: UNREGISTERED_ON_API_CONSOLE
    at android.accounts.AccountManager.convertErrorToException(AccountManager.java:2024)
    at android.accounts.AccountManager.access$400(AccountManager.java:144)
    at android.accounts.AccountManager$AmsTask$Response.onError(AccountManager.java:1867)
    at android.accounts.IAccountManagerResponse$Stub.onTransact(IAccountManagerResponse.java:69)
    at android.os.Binder.execTransact(Binder.java:446)

I cannot find neither doc about this nor other people with the same exception, and I'm quite confused: the call to AccountManager.getAuthToken only provides an account (name and type), a scope, and a callback method, there's no parameter to specify an app or something I could customize in the dev API console.

I'm sure I'm missing something, but what?

like image 350
Xavier Portebois Avatar asked Dec 06 '16 14:12

Xavier Portebois


4 Answers

Well, I finally figured it out. Not sure if I misread the documentation or if there are missing links, but anyway.

Fact is that when you sign a APK and then ask Google for a OAuth2 token, you have to register your signed app through the dev console. It's a security measure based on the app package name and the sha1 fingerprint.

To do that, you have to :

  1. sign your APK, manually or through Gradle or whatever: the Android documentation is pretty clear on this step;
  2. get your sha1 fingerprint; as mention in this SO answer, it's kind of easy on Android Studio: in the Gradle panel, select the signingReport task under your root project and run it - the SHA1 fingerprint will show in the text output;
  3. register your APK through the Google dev console: create a new Credentials / OAuth client id / Android, defined by the SHA1 fingerprint you got and your APK package name.

And voila!

For information, the only official documentation I found explaining the why and how of the two final steps is here: https://developers.google.com/drive/android/auth

like image 160
Xavier Portebois Avatar answered Oct 11 '22 16:10

Xavier Portebois


For anyone still struggling with this, here's what worked for me:

If you enroll your app into the Google Play App Signing program, then your KeyStore is not used de facto to sign the application once it reaches the play store - that's why the fingerprints don't match.

Google removes your certificate and creates a new signing certificate that is used to sign your APK.

In the Play Console go to Release Management -> App signing

If you opted in to Google Play App Signing, you'll see 2 certificates there along with all of their fingerprints. Use the App Signing Certificate fingerprint instead of the Upload Certificate which is your KeyStore.

like image 27
Itai Hanski Avatar answered Oct 11 '22 17:10

Itai Hanski


Don't have the reputation to comment on the accepted answer...

Registering my app in the google dev console wasn't working for me. It turned out that since I was using the debug gradle build, I had to append ".debug" to the package name in google dev console.

I found this out by debugging the Android AccountManager code. When I stepped into the code, I noticed the variable for my app's package name had ".debug" at the end of it. So instead of using the actual package name "com.package.name" in the google dev console, I changed it to "com.package.name.debug" which fixed the UNREGISTERED_ON_API_CONSOLE exception for me.

The reason for this is because my debug buildType in gradle had 'applicationIdSuffix ".debug"'.

like image 38
Jeff Angelini Avatar answered Oct 11 '22 16:10

Jeff Angelini


Thanks Xavier Portebois, your answer really helped. I had to do two more steps.

  • Make sure you enable the API for the service you are using (in my case the Calendar API) in that same google dev console
  • If you are using Google Play App Signing, you do not want to use the debug SHA fingerprint from Android Studio. Instead, go to your app publishing console -> release management -> app signing. Use the SHA-1 fingerprint from the App Signing certificate. 2nd line in this screenshot

Thanks for the informative answer!

like image 28
Emilie Avatar answered Oct 11 '22 17:10

Emilie