SecurityException: uid que llama XXXX es diferente del uid del autenticador

Recibí la excepción anterior cuando bash implementar la aplicación Adaptador de sincronización de muestra. He visto numerosas publicaciones relacionadas con este tema pero ninguna respuesta satisfactoria.

Así que anotaré mi solución aquí en caso de que alguien más tenga el mismo problema.

Algunos otros consejos útiles para solucionar problemas como este.

Primero habilite el registro detallado para algunas tags:

$ 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 

Verás iniciar sesión de la siguiente manera:

 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 

Lo que significa que no hay un autenticador registrado para este tipo de cuenta. Para ver qué autenticadores están registrados, mire el registro al instalar el paquete:

 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 

Tuve el problema de que el descriptor authenticator xml se refería a un recurso de cadena que no se resolvió correctamente durante la instalación:

 android:accountType="@string/account_type" 

Los registros mostraron

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

Reemplazarlo con una cadena normal (no de recursos) resolvió el problema. Esto parece ser específico de Android 2.1.

 android:accountType="com.example.account" 

Primero, verifica la condición explicada en esta publicación :

[…] Si ve un error del AccountManagerService del formulario que caller uid XXXX is different than the authenticator's uid , podría ser un poco engañoso. El ‘autenticador’ en ese mensaje no es su clase de autenticador, es lo que Android entiende que es el autenticador registrado para el tipo de cuenta. La verificación que ocurre dentro de AccountManagerService ve así:

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

Tenga en cuenta que hasAuthenticatorUid() toma el tipo account.type . Aquí es donde lo arruiné. Estaba creando mi Account con un tipo especificado por una constante:

  class LoginTask { Account account = new Account(userId, AuthenticatorService.ACCOUNT_TYPE); ... } class AuthenticatorService extends Service { public static final String ACCOUNT_TYPE = "com.joelapenna.foursquared"; ... } 

pero esta constante no coincide con la definición XML para mi autenticador:

   

Segundo, si eres como yo y quieres insertar la muestra en tu aplicación existente para probarla, asegúrate de usar la clase Constants que es parte de este ejemplo y no del paquete android.provider.SyncStateContract . Debido a que ambas clases usan el mismo nombre de atributo ACCOUNT_TYPE que se utiliza al crear el objeto Account .

En mi caso, el problema era simplemente una falta de coincidencia en accountType declarado en res/xml/authenticator.xml como android:accountType="com.foo" pero referenciado incorrectamente como "foo.com" en la creación de la cuenta:

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

Doh!

Hay pocas partes para implementar una cuenta personalizada …

Para invocar a AccountManager en su actividad, algo así como que ya implementó …

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

En res / xml / authenticator.xml, debe definir sus datos de AccountAuthenticator (responsables de su UID del autenticador). ACCESS_TYPE tiene que ser la misma cadena que su tipo de cuenta definido en este xml.

   

Finalmente, debe definir su servicio como su Manifiesto. No olvide los permisos relevantes para administrar sus cuentas (AUTHENTICATE_ACCOUNTS / USE_CREDENTIALS / GET_ACCOUNTS / MANAGE_ACCOUNTS)

       

Mi error fue suponer que el método AccountManager getAccounts () devolvió cuentas solo asociadas con el contexto de mi aplicación. Cambié de

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

a

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

El mismo error aparecerá si coloca valores incorrectos en sus filtros de intención en su manifiesto. Revisé el tutorial android-dev sobre adaptadores de sincronización y terminé configurando un valor falso para “intent-filter / action android: name” así como también “meta-data / android: name” para syncadapter / accountauthenticator. Este error provocó que aparezcan los mismos errores en los registros.

Para el registro, los valores correctos son: {android.content.SyncAdapter, android.accounts.AccountAuthenticator}

Asegúrese de que su XML de servicio apunte a la ubicación correcta.

Por ejemplo, si su nombre de módulo es

com.example.module.auth

eres servicio android: nombre debe ser

  

en AndriodManifest.xml

En primer lugar, eche un vistazo a los excelentes consejos de depuración de Jan Berkel.

Finalmente, otra cosa que debe verificar es que su proveedor de contenido y los servicios de autenticación y sincronización se declaran como elementos secundarios de la etiqueta de la application .

        

Para mí fue un error muy tonto y fue muy difícil de encontrar.

En authenticator.xml escribí

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

en lugar de

  

que estaba causando este error ¡Espero que esto ayude a alguien!

En mi caso, fueron los permisos en el archivo manifiesto que tuve

  

era todo gorras, cuando lo cambié a

  

problema se fue

También,

Verifique si está tratando el Tipo de cuenta demasiado como una cadena simple.

Tengo la mayor parte de mi código empaquetado en com.mycompany.android

He estado usando el siguiente AccountType con éxito: com.mycompany.android.ACCOUNT .

Ahora deseo utilizar varias cuentas, y cuando bash agregar “.subType” al final de mi cuenta, falla con el

uid de llamada xxxxx es diferente del uid del autenticador

Sin embargo, si uso “_subType” (guión bajo en lugar de punto), funciona bien.

Supongo que, en algún lugar bajo la cubierta, Android intenta tratar com.mycompany.android.ACCOUNT como un nombre de paquete legal, que ciertamente no es.

Entonces, de nuevo:

BAD com.mycompany.android.ACCOUNT.subType

BUENO com.mycompany.android.ACCOUNT_subType

Si obtiene este error, y todas las soluciones anteriores no funcionan para usted. Además, supones que has seguido todo el procedimiento. Es posible que el Servicio de Autenticación sea desarrollado por algún otro desarrollador, que desee utilizar para Agregar Cuentas.

Lo que puede intentar es intentar firmar su aplicación con un almacén de claves de liberación. Ahora ejecuta la aplicación. Supongo que esto debería funcionar para ti.

Aquí hay otra posible solución.

Tuve este error cuando mi usuario se registró en mi aplicación con el mismo correo electrónico que su cuenta de Google Android.

Entonces, cuando intenté accountManager.getAccounts() y buscar este correo electrónico, encontré una cuenta con el mismo correo electrónico PERO con otro tipo de cuenta. Entonces, cuando bash usar esta cuenta (google.com) obtengo este error.

Entonces, la forma correcta de encontrar una cuenta es:

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

También asegúrese de que su AccountAuthenticatorService tenga los filtros de intención de prueba;

es decir.

       

Si obtiene esta excepción en dispositivos Samsung, asegúrese de no estar utilizando el modo seguro .

Si las mismas aplicaciones son de diferentes tiendas, por ejemplo, la tienda de aplicaciones de amazon y Google Play Store, eventualmente se lanzará una excepción de seguridad, ya que la firma de las aplicaciones sería diferente en este caso. Si hubiera planeado usar el mismo autenticador con el fin de iniciar sesión, cualquiera de la aplicación se bloqueará. Me había encontrado con este problema una vez. Especialmente la tienda de aplicaciones de Amazon firmará sus aplicaciones con su propia firma por razones de seguridad.

Nota: Si no hay error de tipeo u otras respuestas mencionadas aquí, verifique la firma de las aplicaciones en caso de inicio de sesión único.

Para aquellos que aún tienen problemas de expiración: https://stackoverflow.com/a/37102317/4171098

En mi caso, accidentalmente definí el AuthenticatorService en el Manifiesto fuera de las tags . Mover la statement dentro de solucionó el problema. Hope ayudará a alguien.