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.


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"

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.


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!


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>

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

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}


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


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>

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!


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ął


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


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.


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

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>


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.


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.