SecurityException: caller uid XXXX отличается от аутентификатора uid

Я получил вышеупомянутое исключение при попытке применить приложение Sample Sync Adapter. Я видел многочисленные сообщения, связанные с этой проблемой, но не удовлетворительный ответ.

Итак, я напишу мое решение здесь, если кто-то еще попадет в ту же проблему.

Ответ 1

Сначала проверьте условие, описанное в этот пост:

[...] Если вы видите ошибку в AccountManagerService формы caller uid XXXX is different than the authenticator uid, это может немного ввести в заблуждение. "Аутентификатор в этом сообщении не является вашим классом аутентификации, его Android понимает, что он является зарегистрированным аутентификатором для типа учетных записей. Проверка, которая происходит в AccountManagerService, выглядит следующим образом:

 private void checkCallingUidAgainstAuthenticator(Account account) {
     final int uid = Binder.getCallingUid();
     if (account == null || !hasAuthenticatorUid(account.type, uid)) {
         String msg = "caller uid " + uid + " is different than the authenticator uid";
         Log.w(TAG, msg);
         throw new SecurityException(msg);
     }
     if (Log.isLoggable(TAG, Log.VERBOSE)) {
         Log.v(TAG, "caller uid " + uid + " is the same as the authenticator uid");
     }
 }

Обратите внимание, что hasAuthenticatorUid() принимает значение account.type. Здесь Иден прикручен. Я создавал свой Account с типом, заданным константой:

 class LoginTask {
     Account account = new Account(userId, AuthenticatorService.ACCOUNT_TYPE);
     ...
 }

 class AuthenticatorService extends Service {
     public static final String ACCOUNT_TYPE = "com.joelapenna.foursquared";
     ...
 }

но эта константа не соответствовала определению XML для моего аутентификатора:

 <account-authenticator xmlns:android="/web/20150729061818/http://schemas.android.com/apk/res/android"
        android:accountType="com.joelapenna.foursquared.account" ... />

Во-вторых, если вы похожи на меня и хотите внедрить образец в существующее приложение для тестирования, убедитесь, что вы используете класс Constants, который является частью этого примера, а не в пакете android.provider.SyncStateContract. Поскольку оба класса используют одно и то же имя атрибута ACCOUNT_TYPE, которое используется при создании объекта Account.

Ответ 2

Некоторые другие полезные советы для отладки таких проблем.

Сначала включите подробное ведение журнала для некоторых тегов:

$ adb shell setprop log.tag.AccountManagerService VERBOSE
$ adb shell setprop log.tag.Accounts VERBOSE
$ adb shell setprop log.tag.Account VERBOSE
$ adb shell setprop log.tag.PackageManager VERBOSE

Вы увидите регистрацию следующим образом:

V/AccountManagerService: initiating bind to authenticator type com.example.account
V/Accounts: there is no service connection for com.example.account
V/Accounts: there is no authenticator for com.example.account, bailing out
D/AccountManagerService: bind attempt failed for Session: expectLaunch true, connected false, stats (0/0/0), lifetime 0.002, addAccount, accountType com.example.account, requiredFeatures null

Это означает, что для этого типа учетной записи нет аутентификатора. Чтобы узнать, какие регистраторы зарегистрированы, просмотрите журнал при установке пакета:

D/PackageManager: encountered new type: ServiceInfo: AuthenticatorDescription {type=com.example.account}, ComponentInfo{com.example/com.example.android.AuthenticatorService}, uid 10028
D/PackageManager: notifyListener: AuthenticatorDescription {type=com.example.account} is added

У меня возникла проблема, что дескриптор xml аутентификатора ссылался на строковый ресурс, который не был правильно разрешен во время установки:

android:accountType="@string/account_type"

Журналы показали

encountered new type: ServiceInfo: AuthenticatorDescription {[email protected]}, ...

Замена его нормальной строкой (не ресурсом) решила проблему. Это похоже на Android 2.1.

android:accountType="com.example.account"

Ответ 3

В моем случае проблема была просто просто несоответствием в типе accountType, объявленном в res/xml/authenticator.xml как android:accountType="com.foo", но неверно указана как "foo.com" при создании учетной записи:

Account newAccount = new Account("dummyaccount", "foo.com");

Doh!

Ответ 4

Есть несколько частей для создания пользовательской учетной записи...

Чтобы вызвать AccountManager в вашей деятельности, что-то подобное вы уже реализовали...

Account account = new Account(username, ACCESS_TYPE);
AccountManager am = AccountManager.get(this);
Bundle userdata = new Bundle();
userdata.putString("SERVER", "extra");

if (am.addAccountExplicitly(account, password, userdata)) {
    Bundle result = new Bundle();
    result.putString(AccountManager.KEY_ACCOUNT_NAME, username);
    result.putString(AccountManager.KEY_ACCOUNT_TYPE, ACCESS_TYPE);
    setAccountAuthenticatorResult(result);
}

В res/xml/authenticator.xml вам необходимо определить данные AccountAuthenticator (отвечающие за ваш идентификатор аутентификатора). ACCESS_TYPE должна быть той же строкой, что и указанный вами тип accountType в этом xml!

<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"
    android:accountType="de.buecherkiste"
    android:icon="@drawable/buecher"
    android:label="@string/app_name"
    android:smallIcon="@drawable/buecher" >
</account-authenticator>

Наконец, вы должны определить свой сервис в своем манифесте. Не забудьте указать соответствующие разрешения для управления своими учетными записями (AUTHENTICATE_ACCOUNTS/USE_CREDENTIALS/GET_ACCOUNTS/MANAGE_ACCOUNTS)

<service android:name=".AuthenticationService">
    <intent-filter>
        <action android:name="android.accounts.AccountAuthenticator" />
    </intent-filter>
    <meta-data android:name="android.accounts.AccountAuthenticator"
        android:resource="@xml/authenticator" />
</service>

Ответ 5

Моя ошибка предполагала, что метод AccountManager getAccounts() возвратил учетные записи, связанные только с моим контекстом приложения. Я изменился с

AccountManager accountManager = AccountManager.get(context);
Account[] accounts = accountManager.getAccounts();

к

AccountManager accountManager = AccountManager.get(context);
Account[] accounts = accountManager.getAccountsByType(Constants.ACCOUNT_TYPE);

Ответ 6

Такая же ошибка появится, если вы поместите неправильные значения в свои фильтры намерений в манифест. Я прошел учебник по android-dev на адаптерах синхронизации и в итоге установил фиктивное значение для "aim-filter/action android: name", а также "meta-data/android: name" для syncadapter/accountauthenticator. Эта ошибка привела к появлению тех же ошибок в журналах.

Для записи правильные значения: {android.content.SyncAdapter, android.accounts.AccountAuthenticator}

Ответ 7

Убедитесь, что ваш XML службы указывает на правильное расположение.

Например, если вы являетесь именем модуля

com.example.module.auth

вы работаете с android: имя должно быть

<service android:name=".module.auth.name-of-authenticator-service-class"...

в AndriodManifest.xml

Ответ 8

Прежде всего, взгляните на Ян Беркель, отличный совет по отладке.

Наконец, еще одна вещь, которую нужно проверить, заключается в том, что ваш поставщик контента и аутентификация, а также службы синхронизации объявлены как дети тега application.

    <application
        ...>
        <activity
            ...(Activity)...
        </activity>
        <provider
            ...(CP service declaration)/>

        <service
            ...(Authentication service declaration)...
        </service>

        <service
            ...(Sync service declaration)... 
        </service>
    </application>

Ответ 9

Для меня это была очень глупая ошибка, и ее было очень трудно найти.

В authenticator.xml я написал

<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android">
xmlns:android="http://schemas.android.com/apk/res/android"
android:accountType="com.myapp"
android:icon="@drawable/ic_launcher"
android:smallIcon="@drawable/ic_launcher"
android:label="@string/app_name"
/>

вместо

<account-authenticator
xmlns:android="http://schemas.android.com/apk/res/android"
android:accountType="com.myapp"
android:icon="@drawable/ic_launcher"
android:smallIcon="@drawable/ic_launcher"
android:label="@string/app_name"
/>

который вызывал эту ошибку. Надеюсь, это поможет кому-то!

Ответ 10

В моем случае это были разрешения в файле манифеста я имел

<uses-permission android:name="ANDROID.PERMISSION.GET_ACCOUNTS"/>

все было закрыто, когда я изменил его на

<uses-permission android:name="ANDROID.PERMISSION.GET_ACCOUNTS"/>

проблема ушла

Ответ 11

Кроме того,

Проверьте, слишком ли вы относитесь к типу AccountType как к файлу plain-old-String.

У меня есть большая часть моего кода, упакованного в com.mycompany.android

Я успешно использовал следующий тип AccountType: com.mycompany.android.ACCOUNT.

Теперь у меня есть желание использовать несколько учетных записей, и когда я пытаюсь подписать ".subType" в конце моей учетной записи, он терпит неудачу с

caller uid xxxxx отличается от аутентификатора uid

Однако, если я использую "_subType" (подчеркивание вместо точки), он отлично работает.

Я предполагаю, что где-то под капотом Android пытается обработать com.mycompany.android.ACCOUNT в качестве юридического имени пакета, которого, безусловно, нет.

Итак, снова:

BAD com.mycompany.android.ACCOUNT.subType

ХОРОШЕЕ com.mycompany.android.ACCOUNT_subType

Ответ 12

Если вы получаете эту ошибку, и все вышеперечисленные решения не работают на вас. Кроме того, вы предполагаете, что соблюдали все процедуры. Возможно, существует вероятность того, что служба проверки подлинности будет разработана другим разработчиком, который вы хотите использовать для добавления учетных записей.

Что вы можете попробовать, попробуйте подписать свое приложение с хранилищем ключей. Теперь вы запускаете приложение. Я полагаю, это должно сработать для вас.

Ответ 13

Вот еще одно возможное решение.

У меня была эта ошибка, когда мой пользователь был зарегистрирован в моем приложении с тем же адресом электронной почты, что и его учетная запись Google Android.

Итак, когда я пытался accountManager.getAccounts() и искал это электронное письмо, я нашел учетную запись с тем же адресом электронной почты, но с другим типом учетной записи. Поэтому, пытаясь использовать эту (google.com) учетную запись, я получаю эту ошибку.

Итак, правильный способ найти учетную запись:

public Account findAccount(String accountName) {
    for (Account account : accountManager.getAccounts())
        if (TextUtils.equals(account.name, accountName) && TextUtils.equals(account.type, "myservice.com"))
            return account;
    return null;
}

Ответ 14

Также убедитесь, что у вашей учетной записи AccountAuthenticatorService есть фильтры, предназначенные для проверки;

т.

<service android:name=".service.AccountAuthenticatorService">
        <intent-filter>
            <action android:name="android.accounts.AccountAuthenticator" />
        </intent-filter>
        <meta-data android:name="android.accounts.AccountAuthenticator"
                    android:resource="@xml/authenticator" />
 </service>

Ответ 15

Если вы получили это исключение на устройствах Samsung, убедитесь, что вы не используете безопасный режим .

Ответ 16

Если те же приложения из разных магазинов, например, в магазине приложений amazon и в магазине google play, в конечном итоге исключение безопасности будет выбрано, так как подпись приложений будет отличаться в этом случае. Если вы планировали использовать тот же аутентификатор для цель одного входа, любое из приложений будет аварийно завершено. Однажды я столкнулся с этой проблемой. Особенно магазин приложений amazon подпишет свои приложения со своей собственной подписью с целью обеспечения безопасности.

Примечание. Если нет опечатки или других ответов, упомянутых здесь, проверьте подпись приложений в случае единого входа.

Ответ 17

Для тех, кто все еще проверяет проблему: fooobar.com/info/68136/...

В моем случае я случайно определил AuthenticatorService в манифесте вне тегов <application>. Перемещение декларации внутри <application> исправлена ​​проблема. Надежда поможет кому-то.