SecurityException: identyfikator dzwoniącego XXXX jest inny niż identyfikator uwierzytelniającego

84

Powyższy wyjątek otrzymałem podczas próby zaimplementowania aplikacji Sample Sync Adapter. Widziałem wiele postów związanych z tym problemem, ale brak satysfakcjonującej odpowiedzi.

Dlatego zanotuję tutaj moje rozwiązanie na wypadek, gdyby ktoś inny wpadł w ten sam problem.

Paweł
źródło
Dzięki. Natknąłem się na ten problem i dzięki twojemu wpisowi mogłem szybciej znaleźć rozwiązanie.
Damian,
4
Niestety, w międzyczasie opublikowany link został uszkodzony. Czy ktoś ma alternatywę?
johsin18

Odpowiedzi:

54

Kilka innych przydatnych wskazówek dotyczących debugowania takich problemów.

Najpierw włącz szczegółowe rejestrowanie niektórych tagów:

$ 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

Zobaczysz takie rejestrowanie:

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

Co oznacza, że ​​nie ma zarejestrowanego wystawcy uwierzytelnienia dla tego typu konta. Aby zobaczyć, które uwierzytelniacze są zarejestrowane, obejrzyj dziennik podczas instalowania pakietu:

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

Miałem problem polegający na tym, że deskryptor xml elementu uwierzytelniającego odnosił się do zasobu ciągu, który nie został poprawnie rozwiązany podczas instalacji:

android:accountType="@string/account_type"

Dzienniki pokazały

encountered new type: ServiceInfo: AuthenticatorDescription {type=@2131231194}, ...

Zastąpienie go zwykłym ciągiem (nie zasobem) rozwiązało problem. Wydaje się, że jest to specyficzne dla Androida 2.1.

android:accountType="com.example.account"
Jan Berkel
źródło
Pomogło mi to zlikwidować problem.
skygeek
44

Najpierw sprawdź stan wyjaśniony w tym poście :

[…] Jeśli widzisz błąd AccountManagerServicew formularzu caller uid XXXX is different than the authenticator's uid, może to być trochę mylące. „Authenticator” w tej wiadomości nie jest twoją klasą uwierzytelniającą, to jest to, co Android rozumie jako zarejestrowany autentykator dla typu konta. Sprawdzenie, które ma miejsce w ramach AccountManagerServicewygląda następująco:

 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");
     }
 }

Zauważ, że hasAuthenticatorUid()zajmuje account.type. Tutaj schrzaniłem sprawę. Tworzyłem moje Accountz typem określonym przez stałą:

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

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

ale ta stała nie pasuje do definicji XML mojego wystawcy uwierzytelnienia:

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

Po drugie, jeśli jesteś podobny do mnie i chcesz osadzić próbkę w istniejącej aplikacji w celu przetestowania, upewnij się, że używasz Constantsklasy, która jest częścią tego przykładu, a nie w android.provider.SyncStateContractpakiecie. Ponieważ obie klasy używają tej samej nazwy atrybutu, ACCOUNT_TYPEktóra jest używana podczas tworzenia Accountobiektu.

Paweł
źródło
Dzięki! Twoja pierwsza kontrola rozwiązała problem. I zgadnij co, w nowym projekcie zupełnie zapomniałem o pliku xml modułu uwierzytelniającego.!
George Pligoropoulos,
7
Nadal widzę ten problem, ale tylko dla niektórych moich użytkowników. Dokładnie sprawdziłem, czy typ android: accountType w pliku autentykator.xml jest zgodny ze stałą w mojej usłudze GenericAccountsService. Wiem również, że ten wyjątek nie występuje w przypadku zdecydowanej większości użytkowników moich aplikacji, ale w moich dziennikach awarii od czasu do czasu widzę awarię dla kilku użytkowników. Dowolny pomysł? Czy plik autentykator.xml może zostać w jakiś sposób zmodyfikowany, aby to spowodować?
Zapalony
3
@clu Czy kiedykolwiek udało Ci się rozwiązać swój problem? Stoję przed identycznym scenariuszem. Ten błąd pojawia się tylko u niewielkiej mniejszości moich użytkowników: głównie na HTC One X, HTC One SV i HTC Desire 500, a także na wielu innych urządzeniach.
chandsie
1
@chandsie To samo tutaj. Wydaje się, że tylko urządzenia HTC mają ten problem. Działa dobrze na każdym innym urządzeniu.
Kiran Kumar
@clu Mam również ten sam problem. Czy byłeś w stanie rozwiązać ten problem lub znaleźć jego podstawową przyczynę?
wasaig
25

W moim przypadku problemem była po prostu niezgodność w accountType zadeklarowanym res/xml/authenticator.xmljako, android:accountType="com.foo"ale przywoływanym nieprawidłowo, jak "foo.com"podczas tworzenia konta:

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

No!

Farrukh Najmi
źródło
1
Cześć, w moim przypadku accountType w xml iw obiekcie newAccount oba są takie same. Nadal pokazuje, że identyfikator dzwoniącego XXXX jest inny niż błąd uid wystawcy uwierzytelnienia. czemu?
Vijay Vankhede
10

Jest kilka części do wdrożenia konta niestandardowego ...

Aby wywołać AccountManagera w swoim działaniu, coś takiego, jak już zaimplementowałeś ...

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);
}

W res / xml / autentikator.xml musisz zdefiniować swoje dane AccountAuthenticator (odpowiedzialne za Twój identyfikator UID Authenticatora). ACCESS_TYPE musi być tym samym ciągiem, co zdefiniowany typ konta w tym 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>

Wreszcie musisz zdefiniować swoją usługę jako Manifest. Nie zapomnij o odpowiednich uprawnieniach do zarządzania swoimi kontami (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>
DocFoster
źródło
Uważaj na TYPO! AuthenticaTAtionService. Poza tym to faktycznie name = ". AuthenticationService" najwyraźniej (z kropką) i pokazuje to na czerwono w moim przypadku, ale i tak działa.
FlorianB,
5

Mój błąd polegał na założeniu, że metoda AccountManager getAccounts () zwróciła tylko konta powiązane z kontekstem mojej aplikacji. Zmieniłem się z

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

do

AccountManager accountManager = AccountManager.get(context);
Account[] accounts = accountManager.getAccountsByType(Constants.ACCOUNT_TYPE);
PLA
źródło
4

Ten sam błąd pojawi się, jeśli umieścisz nieprawidłowe wartości w filtrach intencji w swoim manifeście. Przeszedłem przez samouczek android-dev na temat adapterów synchronizacji i ostatecznie ustawiłem fałszywą wartość dla „intent-filter / action android: name” oraz „meta-data / android: name” dla syncadapter / accountauthenticator. Ten błąd spowodował pojawienie się tych samych błędów w dziennikach.

Dla rekordu prawidłowe wartości to: {android.content.SyncAdapter, android.accounts.AccountAuthenticator}

clearfix
źródło
2

Upewnij się, że kod XML usługi wskazuje poprawną lokalizację.

Na przykład, jeśli nazwa modułu to

com.example.module.auth

jesteś serwisem android: nazwa powinna być

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

w AndriodManifest.xml

jrea
źródło
2

Po pierwsze, spójrz jeszcze raz na doskonałe rady dotyczące debugowania Jana Berkela.

Na koniec kolejną rzeczą do sprawdzenia jest to, że dostawca treści oraz usługi uwierzytelniania i synchronizacji są zadeklarowane jako elementy applicationpodrzędne tagu.

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

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

        <service
            ...(Sync service declaration)... 
        </service>
    </application>
Geoff
źródło
Dziecko <aplikacji>! Zrobiłem to dla mnie, dzięki! I jest to <service android: name = ". AuthenticationService">
FlorianB,
2

Dla mnie był to bardzo głupi błąd i bardzo trudno go było znaleźć.

Napisałem w pliku authenticationator.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"
/>

zamiast

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

który powodował ten błąd. Mam nadzieję, że to komuś pomoże!

penduDev
źródło
2

W moim przypadku były to uprawnienia w pliku manifestu

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

to były czapki, kiedy zmieniłem to na

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

problem zniknął

Ivan Vazhnov
źródło
1

Również,

Sprawdź, czy nie traktujesz AccountType zbyt podobnie jak zwykłego starego ciągu.

Większość mojego kodu jest spakowana pod adresem com.mycompany.android

Z powodzeniem używam następującego AccountType: com.mycompany.android.ACCOUNT .

Teraz chcę używać wielu kont, a kiedy próbuję dodać „.subType” na końcu mojego konta, kończy się to niepowodzeniem.

identyfikator dzwoniącego xxxxx różni się od identyfikatora użytkownika uwierzytelniającego

Jeśli jednak użyję „_subType” (podkreślenie zamiast kropki), działa dobrze.

Domyślam się, że gdzieś pod maską Android próbuje traktować com.mycompany.android.ACCOUNT jako legalną nazwę pakietu, czym z pewnością nie jest.

Więc znowu:

BAD com.mycompany.android.ACCOUNT.subType

DOBRY com.mycompany.android.ACCOUNT_subType

Darren Hicks
źródło
1

Jeśli otrzymujesz ten błąd, a wszystkie powyższe rozwiązania nie działają dla Ciebie. Zakładasz również, że wykonałeś całą procedurę. Może się zdarzyć, że usługa uwierzytelniania została opracowana przez innego programistę, z którego chcesz korzystać w celu dodawania kont.

Możesz spróbować podpisać swoją aplikację za pomocą magazynu kluczy wydania. Teraz uruchom aplikację. Przypuszczam, że to powinno działać dla Ciebie.

Ali Ashraf
źródło
1

Oto kolejne możliwe rozwiązanie.

Wystąpił ten błąd, gdy mój użytkownik był zarejestrowany w mojej aplikacji przy użyciu tego samego adresu e-mail, co jego konto Google na Androida.

Tak więc, kiedy próbowałem accountManager.getAccounts()znaleźć ten e-mail, znalazłem konto z tym samym adresem e-mail, ALE z innym typem konta. Tak więc podczas próby użycia tego konta (google.com) pojawia się ten błąd.

Tak więc właściwy sposób na znalezienie konta to:

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;
}
konmik
źródło
Zamiast accountManager.getAccountsByType("myservice.com")tego możesz zadzwonić .
nickgrim,
0

Upewnij się również, że usługa AccountAuthenticatorService ma filtry intencji dowodu;

to znaczy.

<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>
Løkling
źródło
0

Jeśli dostaniesz ten wyjątek na urządzeniach Samsung, upewnij się, że nie używasz trybu awaryjnego .

rocknow
źródło
0

Jeśli te same aplikacje pochodzą z innego sklepu, na przykład sklepu z aplikacjami amazon i sklepu Google Play, ostatecznie zostanie wyrzucony wyjątek bezpieczeństwa, ponieważ podpis aplikacji będzie inny w tym przypadku. Zaloguj się, każda z aplikacji ulegnie awarii. raz napotkałem ten problem. Zwłaszcza sklep z aplikacjami amazon podpisywałby swoje aplikacje własnym podpisem ze względów bezpieczeństwa.

Uwaga: jeśli nie ma błędu literowego lub innych odpowiedzi wymienionych tutaj, sprawdź podpis aplikacji w przypadku pojedynczego logowania.

JerryWild
źródło
0

Dla tych, którzy wciąż doświadczają problemu: https://stackoverflow.com/a/37102317/4171098

W moim przypadku przypadkowo zdefiniowałem usługę AuthenticatorService w manifeście poza <application>tagami. Przeniesienie deklaracji do środka <application>rozwiązało problem. Nadzieja komuś pomoże.

Mateusz Włodarczyk
źródło