SecurityException: uid вызывающего абонента XXXX отличается от uid аутентификатора


84

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

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


Благодарю. Я столкнулся с этой проблемой и смог быстрее найти решение благодаря вашему сообщению.
— Дамиан

4
К сожалению, размещенная ссылка тем временем не работает. Есть ли у кого-нибудь альтернатива?
— johsin18

Ответы:


54

Еще несколько полезных советов по устранению подобных проблем.

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

$ 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 {type=@2131231194}, ...

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

android:accountType="com.example.account"

Это помогло мне решить проблему.
— skygeek

44

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

[...] Если вы видите ошибку в AccountManagerServiceформе caller uid XXXX is different than the authenticator's 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's 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's 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объекта.


Благодаря! ваша первая проверка решила проблему. И угадайте, что в новом проекте я совершенно забыл об XML-файле аутентификатора.!
— Джордж Плигоропулос,

7
Я все еще вижу эту проблему, но только у некоторых моих пользователей. Я дважды проверил, что android: accountType в файле Authenticator.xml соответствует константе в моей GenericAccountsService. Я также знаю, что это исключение не возникает для подавляющего большинства пользователей моих приложений, но в моих журналах сбоев время от времени я вижу сбой для нескольких пользователей. Есть идеи? Можно ли как-то изменить файл Authenticator.xml, чтобы вызвать это?
— LyteSpeed

3
@clu Удалось ли вам когда-нибудь решить свою проблему? Я столкнулся с идентичным сценарием. Эта ошибка возникает только у небольшого меньшинства моих пользователей: в основном на HTC One X, HTC One SV и HTC Desire 500, а также на некоторых других устройствах.
— chandsie

1
@chandsie То же самое и здесь. Только устройства HTC, похоже, имеют эту проблему. Он отлично работает с любым другим устройством.
— Киран Кумар

@clu Я тоже столкнулся с той же проблемой. Удалось ли вам решить эту проблему или найти ее первопричину?
— wasaig 05

25

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

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

Дох!


1
Привет, В моем случае accountType в xml и в объекте newAccount одинаковы. Тем не менее, он показывает, что uid вызывающего абонента XXXX отличается от ошибки uid аутентификатора. Почему?
— Виджай Ванкхеде

10

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

Чтобы вызвать 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 (отвечающие за ваш UID Authenticator). 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>

Наконец, вы должны определить свою службу Manifest. Не забудьте соответствующие разрешения для управления своими учетными записями (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>

Остерегайтесь TYPO! AuthenticaTAtionService. Кроме того, на самом деле это name = ". AuthenticationService", очевидно (с точкой), и в моем случае он отображается красным цветом, но он все равно работает.
— FlorianB

5

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

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

к

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

4

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

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


2

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

Например, если ваше имя модуля

com.example.module.auth

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

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

в AndriodManifest.xml


2

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

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

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

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

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

Дочерний объект <application>! Сделал это для меня, спасибо! И это <service android: name = ". AuthenticationService">
— FlorianB

2

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

В 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"
/>

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


2

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

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

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

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

проблема исчезла


1

Также,

Проверьте, не слишком ли вы относитесь к AccountType как к старой простой строке.

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

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

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

uid вызывающего абонента xxxxx отличается от uid аутентификатора

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

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

Итак, еще раз:

ПЛОХО com.mycompany.android.ACCOUNT.subType

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


1

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

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


1

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

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

Итак, когда я попытался 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;
}

Вы могли бы accountManager.getAccountsByType("myservice.com")вместо этого позвонить .
— nickgrim

0

Также убедитесь, что ваш 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>


0

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

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


0

Для тех, кто все еще сталкивается с проблемой: https://stackoverflow.com/a/37102317/4171098

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.