SecurityException:调用者uid XXXX与认证者的uid不同

问题描述:

尝试实施Sample Sync Adapter应用程序时,我收到上述异常。我看到许多与这个问题有关的帖子,但没有令人满意的答复。SecurityException:调用者uid XXXX与认证者的uid不同

所以我会在这里记下my solution以防其他人进入相同的问题。

+0

谢谢。我遇到了这个问题,并且能够更快地找到解决方案,这要归功于您的帖子。 – Damian 2011-02-26 16:15:04

+4

不幸的是,发布的链接在此期间被破坏。有人有另一种选择吗? – Joqn 2013-05-31 14:40:00

首先,检查条件对this post解释说:

[...]如果你看到从形式caller uid XXXX is different than the authenticator's uidAccountManagerService一个错误,它可能是一个有点误导。该消息中的“身份验证器”不是您的身份验证器类,它是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对象时使用的相同属性名称ACCOUNT_TYPE

+0

谢谢!你的第一张支票解决了问题。猜猜看,在一个新的项目中,我忘记了所有关于authenticator xml文件。 – 2013-12-12 20:41:03

+6

我仍然看到此问题,但仅限于我的部分用户。我仔细检查了authenticator.xml文件中的android:accountType与我的GenericAccountsService中的常量匹配。我也知道绝大多数应用用户不会出现这种异常,但是在我的崩溃日志中,我偶尔会看到少数用户的崩溃。任何想法?可以修改authenticator.xml文件以某种方式导致此问题? – clu 2014-11-25 20:53:33

+3

@clu您是否曾经能够解决您的问题?我面临着一个相同的情况。这个错误只对我的一小部分用户有用:主要是HTC One X,HTC One SV和HTC Desire 500,以及许多其他设备。 – chandsie 2015-07-28 21:18:59

一些其他有用的技巧来调试这样的问题。

首先启用详细日志记录的一些标签:

$ 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 {[email protected]}, ... 

与普通的字符串(而不是资源)解决了这个问题更换它。这似乎是Android 2.1特有的。

android:accountType="com.example.account" 

此外,

检查,看看你是太多治疗ACCOUNTTYPE像一个普通的老字符串。com.mycompany.android.ACCOUNT

我有我的大部分代码下包装我一直在使用成功以下ACCOUNTTYPE com.mycompany.android

现在我不得不使用多个帐户的愿望,当我试着在后面加上“.subType”我的账户年底的临近,它无法与

主叫UID xxxxx是比不同authenticator's uid

但是,如果我使用“_subType”(下划线而不是点),它工作正常。

我的猜测是,Android正试图将com.mycompany.android.ACCOUNT作为合法的软件包名称进行处理,而这肯定不是。

因此,再次:

BAD com.mycompany.android.ACCOUNT.subType

GOOD com.mycompany.android.ACCOUNT_subType

我的错误是假设的AccountManager getAccounts( )方法返回的帐户只与我的应用程序上下文关联。我从

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

改为

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

确保您的服务XML指向正确的位置。

举例来说,如果你的模块名称是

com.example.module.auth

你的Android服务:名称应该是

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

.xml

还要确保您的AccountAuthenticatorService具有pr通过意图过滤器;

即。

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

有实现自定义帐户几部分组成?

要在活动调用的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数据(负责你的Authenticator UID)。 ACCESS_TYPE必须与您在此xml中定义的accountType相同的字符串!

<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 /许可权)

<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> 
+0

小心TYPO! AuthenticaTAtionService。再加上它实际上是name =“。AuthenticationService”显然(带点),它在我的情况下显示为红色,但它仍然有效。 – FlorianB 2017-02-10 00:29:11

在我的情况下,问题很简单地ACCOUNTTYPE不匹配的res/xml/authenticator.xml作为android:accountType="com.foo"声明,但在错误引用为"foo.com"创建账户:

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

Doh!

+1

嗨,在我的情况下,xml和newAccount对象中的accountType都是相同的。它仍然显示调用者uid XXXX与认证者的uid错误不同。为什么? – vsvankhede 2015-04-10 06:30:22

如果您在清单中的意图过滤器中输入了不正确的值,则会出现相同的错误。 我经历了关于同步适配器的android-dev教程,并最终为syncadapter/accountauthenticator设置了“intent-filter/action android:name”以及“meta-data/android:name”的伪造值。这个错误导致了相同的错误出现在日志中。

为了记录在案,正确的价值观是:{android.content.SyncAdapter,android.accounts.AccountAuthenticator}

首先,再看看扬伯克尔出色的调试建议。

最后,要检查的另一件事是您的内容提供商和身份验证以及同步服务声明为application标记的子项。

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

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

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

的小孩!对我来说,谢谢!它是 FlorianB 2017-02-10 00:30:12

如果您遇到此错误,并且上述所有解决方案均无法为您工作,另外,你还假定你已经遵循了所有的程序。身份验证服务可能由其他开发人员开发,您希望使用它来添加帐户。

您可以尝试的是尝试使用发行密钥库对您的应用程序进行签名。现在你运行该应用程序。我想这应该适合你。

对我来说这是一个非常愚蠢的错误,很难找到。

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

这是导致该错误。希望这可以帮助别人!

在我的情况下,它是在manifest文件 权限,我有

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

它是全部大写,当我把它改成

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

问题不见了

这里是另一个一种可能的解决方

我有这个错误,当我的用户在我的应用程序中注册与他的Android谷歌帐户相同的电子邮件。

因此,当我试图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; 
} 
+0

您可以调用'accountManager.getAccountsByType(“myservice.com”)'代替。 – nickgrim 2016-02-24 15:11:20

+0

哇,棘手!谢谢。 :d – konmik 2016-02-25 15:23:02

如果你得到这个异常的三星设备确保您不使用safe mode

如果相同的应用程序来自不同的商店,例如amazon应用程序商店和谷歌Play商店,最终会抛出安全性异常,因为这种情况下应用程序的签名会有所不同。如果您计划使用相同的身份验证器单点登录的目的,任何一个应用程序都会崩溃。我曾遇到过这个麻烦。尤其是亚马逊应用商店会出于安全考虑而对自己的应用程序进行签名。

注:如果没有错字的错误或这里提到的其它一些问题,请检查该应用程序的签名单点登录的情况下,

对于那些谁仍然expierienced问题:https://stackoverflow.com/a/37102317/4171098

在我的情况下,我无意中在<application>标签之外的Manifest 中定义了AuthenticatorService。移动内部的声明 <application>修复了这个问题。希望会帮助别人。