SecurityException: l'uid del chiamante XXXX è diverso dall'uid dell'autenticatore


84

Ho ricevuto l'eccezione precedente durante il tentativo di implementare l'applicazione Sample Sync Adapter. Ho visto numerosi post relativi a questo problema ma nessuna risposta soddisfacente.

Quindi annoterò qui la mia soluzione nel caso in cui qualcun altro si imbattesse nello stesso problema.


Grazie. Mi sono imbattuto in questo problema e sono riuscito a trovare la soluzione più rapidamente grazie al tuo post.
Damian

4
Sfortunatamente, il link pubblicato nel frattempo è stato interrotto. Qualcuno ha un'alternativa?
johsin18

Risposte:


54

Alcuni altri suggerimenti utili per eseguire il debug di problemi come questo.

Abilita prima la registrazione dettagliata per alcuni tag:

$ 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

Vedrai la registrazione in questo modo:

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

Ciò significa che non esiste un autenticatore registrato per questo tipo di account. Per vedere quali autenticatori sono registrati, guarda il registro durante l'installazione del pacchetto:

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

Ho avuto il problema che il descrittore xml dell'autenticatore si riferisse a una risorsa stringa che non è stata risolta correttamente durante l'installazione:

android:accountType="@string/account_type"

I registri hanno mostrato

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

Sostituendolo con una stringa normale (non risorsa) ha risolto il problema. Questo sembra essere specifico per Android 2.1.

android:accountType="com.example.account"

Questo mi ha aiutato a risolvere il problema.
skygeek

44

Innanzitutto, controlla le condizioni spiegate in questo post :

[...] Se vedi un errore dal AccountManagerServicedel modulo caller uid XXXX is different than the authenticator's uid, potrebbe essere un po 'fuorviante. L '"autenticatore" in quel messaggio non è la tua classe autenticatore, è ciò che Android intende essere l'autenticatore registrato per il tipo di account. Il controllo che avviene all'interno di questo AccountManagerServiceaspetto:

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

Nota che hasAuthenticatorUid()accetta l'estensione account.type. Qui è dove avevo sbagliato. Stavo creando il mio Accountcon un tipo specificato da una costante:

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

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

ma questa costante non corrispondeva alla definizione XML per il mio autenticatore:

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

In secondo luogo, se sei come me e desideri incorporare l'esempio nella tua app esistente per il test, assicurati di utilizzare la Constantsclasse che fa parte di questo esempio e non nel android.provider.SyncStateContractpacchetto. Perché entrambe le classi utilizzano lo stesso nome di attributo ACCOUNT_TYPEutilizzato durante la creazione Accountdell'oggetto.


Grazie! il tuo primo controllo ha risolto il problema. E indovina un po ', in un nuovo progetto mi ero dimenticato completamente del file xml dell'autenticatore.
George Pligoropoulos

7
Sto ancora riscontrando questo problema, ma solo per alcuni dei miei utenti. Ho ricontrollato che android: accountType nel file authenticator.xml corrisponda alla costante nel mio GenericAccountsService. So anche che questa eccezione non si verifica per la stragrande maggioranza degli utenti delle mie app, ma nei miei registri di arresto anomalo ogni tanto vedo l'arresto anomalo per una manciata di utenti. Qualche idea? Il file authenticator.xml può essere modificato in qualche modo per causare ciò?
LyteSpeed

3
@clu Sei mai riuscito a risolvere il tuo problema? Sto affrontando uno scenario identico. Questo errore si presenta solo per una piccola minoranza dei miei utenti: principalmente su HTC One X, HTC One SV e HTC Desire 500, oltre a un'infarinatura di molti altri dispositivi.
chandsie

1
@chandsie Stesso qui. Solo i dispositivi HTC sembrano avere questo problema. Funziona bene per ogni altro dispositivo.
Kiran Kumar

@clu Anch'io sto affrontando lo stesso problema. Sei riuscito a risolverlo o trovarne la causa principale?
wasaig

25

Nel mio caso il problema era semplicemente una mancata corrispondenza in accountType dichiarato res/xml/authenticator.xmlcome android:accountType="com.foo"ma referenziato in modo errato come "foo.com"nella creazione dell'account:

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

Doh!


1
Ciao, Nel mio caso accountType in xml e in newAccount object sono entrambi uguali. Ancora mostra che l'uid del chiamante XXXX è diverso dall'errore dell'uid dell'autenticatore. perché?
Vijay Vankhede

10

Ci sono poche parti per implementare un account personalizzato ...

Per richiamare AccountManager nella tua attività, qualcosa di simile che hai già implementato ...

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

In res / xml / authenticator.xml devi definire i tuoi dati AccountAuthenticator (responsabile per il tuo Authenticator UID). ACCESS_TYPE deve essere la stessa stringa del tuo accountType definito in questo 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>

Infine devi definire il tuo servizio il tuo Manifest. Non dimenticare le autorizzazioni pertinenti per la gestione dei tuoi account (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>

Attenzione al TYPO! AuthenticaTAtionService. Inoltre è apparentemente name = ". AuthenticationService", (con un punto) e lo mostra in rosso nel mio caso, ma funziona comunque.
FlorianB

5

Il mio errore era supporre che il metodo AccountManager getAccounts () restituisse account associati solo al contesto della mia applicazione. Sono cambiato da

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

per

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

4

Lo stesso errore apparirà se inserisci valori errati nei filtri di intent nel tuo manifest. Ho seguito il tutorial di android-dev sugli adattatori di sincronizzazione e ho finito per impostare un valore fasullo per "intent-filter / action android: name" e "meta-data / android: name" per syncadapter / accountauthenticator. Questo errore ha causato la visualizzazione degli stessi errori nei log.

Per la cronaca, i valori corretti sono: {android.content.SyncAdapter, android.accounts.AccountAuthenticator}


2

Assicurati che il tuo servizio XML punti alla posizione corretta.

Ad esempio, se il nome del tuo modulo è

com.example.module.auth

sei un servizio Android: il nome dovrebbe essere

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

in AndriodManifest.xml


2

Prima di tutto, dai un'altra occhiata agli eccellenti consigli di debug di Jan Berkel.

Infine, un'altra cosa da controllare è che il tuo provider di contenuti e i servizi di autenticazione e sincronizzazione siano dichiarati come figli di application tag.

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

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

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

Figlio di <applicazione>! L'ha fatto per me, grazie! Ed è <service android: name = ". AuthenticationService">
FlorianB

2

Per me è stato un errore molto sciocco ed è stato molto difficile da trovare.

In authenticator.xml ho scritto

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

invece di

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

che stava causando questo errore. Spero che questo aiuti qualcuno!


2

Nel mio caso erano le autorizzazioni nel file manifest che avevo

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

era tutto maiuscolo, quando l'ho cambiato in

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

problema era andato


1

Anche,

Controlla se stai trattando AccountType troppo come una semplice vecchia stringa.

Ho la maggior parte del mio codice impacchettato in com.mycompany.android

Ho utilizzato con successo il seguente AccountType: com.mycompany.android.ACCOUNT .

Ora desidero utilizzare più account e quando provo l'approccio di aggiungere ".subType" alla fine del mio account, non riesce con il

caller uid xxxxx è diverso dall'uid dell'autenticatore

Tuttavia, se uso "_subType" (trattino basso invece di punto), funziona bene.

La mia ipotesi è che da qualche parte sotto il cofano Android stia cercando di trattare com.mycompany.android.ACCOUNT come un nome di pacchetto legale, cosa che sicuramente non è.

Quindi, ancora:

BAD com.mycompany.android.ACCOUNT.subType

GOOD com.mycompany.android.ACCOUNT_subType


1

Se ricevi questo errore e tutte le soluzioni di cui sopra non funzionano per te. Inoltre, presumi di aver seguito tutta la procedura. Potrebbe esserci la possibilità che il servizio di autenticazione sia sviluppato da un altro sviluppatore, che desideri utilizzare per aggiungere account.

Quello che puoi provare è provare a firmare la tua applicazione con un keystore di rilascio. Ora esegui l'applicazione. Suppongo che questo dovrebbe funzionare per te.


1

Ecco un'altra possibile soluzione.

Ho riscontrato questo errore quando il mio utente è stato registrato nella mia app con la stessa e-mail del suo account Google Android.

Quindi, quando ho provato a accountManager.getAccounts()cercare questa e-mail, ho trovato un account con la stessa e-mail MA con un altro tipo di account. Quindi, quando provo a utilizzare questo account (google.com) ottengo questo errore.

Quindi, il modo giusto per trovare un account è:

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

Potresti chiamare accountManager.getAccountsByType("myservice.com")invece.
nickgrim

0

Assicurati inoltre che il tuo AccountAuthenticatorService abbia i filtri di intento del prover;

cioè.

<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

Se le stesse app provengono da un negozio diverso, ad esempio Amazon App Store e Google Play Store, alla fine verrà generata un'eccezione di sicurezza poiché la firma delle app sarebbe diversa in questo caso.Se avessi pianificato di utilizzare lo stesso autenticatore allo scopo di single accedi, una delle app si arresta in modo anomalo. avevo riscontrato questo problema una volta. Soprattutto l'app store di Amazon firmerebbe le sue app con la propria firma ai fini della sicurezza.

Nota: se non ci sono errori di battitura o altre risposte menzionate qui, controlla la firma delle app in caso di accesso singolo.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.