Question

i have a custom authenticator, and i'd like to expose the user / password to other applications. to protect from any random app obtaining the credentials, i'd like to perform something like a permissions check in my custom authenticator's getAuthToken() method. what's the correct method?

i tried this,

    int p = context.checkCallingPermission("com.whatever.AUTH");
    if (p != PackageManager.PERMISSION_GRANTED) {

where "com.whatever.AUTH" is defined in the app hosting my authenticator,

<permission android:name="com.vmware.horizon.AUTH" />

however, in my test app that does not have a uses-permission in it's manifest, when i request the account,

    AccountManagerFuture<Bundle> future = am.getAuthToken(new Account(
            "com.whatever", "com.whatever"),
            "com.whatever", new Bundle(), this,
            new AccountManagerCallback<Bundle>() {

                @Override
                public void run(AccountManagerFuture<Bundle> future) {
                                        String token  = result.getString(AccountManager.KEY_AUTHTOKEN);

                }
            }, handler);

i successfully obtain the auth token. debugging shows that the call through to my authenticator's getAuthToken() method happens, but the check permission call returned "granted".

EDIT: if i get the package name from the context i'm using to call checkCallingPermission() it is the package name of the app hosting the custom authenticator. if i get the calling PID, UID they are 0 and 1000, respectively.

any ideas?

Was it helpful?

Solution

When looking at the Android source code, I noticed that the account manager service sets the caller's pid and uid on the Bundle as AccountManager.KEY_CALLER_PID and AccountManager.KEY_CALLER_UID.

You can use getInt() on the bundle to find out the real caller's pid and uid in your getAppToken method.

One other useful bit of information that can be hard to find. The getAppToken method is often only called once since the account manager service caches the result. If you want to be able to manage the token more actively, you can disable caching by adding meta-data to your manifest entry:

<service android:name=".authenticator.AccountAuthenticatorService">
  <meta-data android:name="android.accounts.AccountAuthenticator" android:resource="@xml/authenticator"/>
  <meta-data android:name="android.accounts.AccountAuthenticator.customTokens" android:value="1"/>
</service>

Here is what the authenticator xml looks like:

<?xml version="1.0" encoding="utf-8"?>
<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"
  android:accountType="com.your.account.type"
  android:customTokens="true"
  android:icon="@drawable/logo"
  android:smallIcon="@drawable/logo"
  android:label="@string/app_name_long"/>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top