安全异常:调用方UID XXXX与身份验证器的UID不同

84

在尝试实现示例同步适配器应用程序时,我遇到了上述异常。我看到了许多与此问题相关的帖子,但没有令人满意的回复。

因此,我会在这里记录我的解决方案,以防其他人遇到相同的问题。


谢谢。我遇到了这个问题,由于你的帖子,我能够更快地找到解决方案。 - Damian
4
很遗憾,链接在此期间已经失效。有没有其他可用的替代链接? - johsin18
17个回答

54

还有一些有用的提示可以帮助调试此类问题。

首先,对于某些标签启用详细日志记录:

$ 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 {type=@2131231194}, ...

将其替换为普通字符串(而不是资源)可以解决问题。这似乎只出现在Android 2.1中。

android:accountType="com.example.account"

这帮助我解决了问题。 - skygeek

44

首先,检查在这篇文章中解释的条件:

[...] 如果你看到一个来自AccountManagerService的错误信息,形式为caller uid XXXX is different than the authenticator's uid,那么这可能会有点误导。在该消息中,“认证器”不是指你的认证器类,而是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_TYPE,该属性名称在创建Account对象时被使用。


谢谢!你的第一个检查解决了这个问题。你猜怎么着,在一个新项目中我忘记了认证器 XML 文件。 - George Pligoropoulos
7
我仍然看到这个问题,但只有一些用户会遇到。我已经仔细检查了authenticator.xml文件中的android:accountType与我的GenericAccountsService中的常量是否匹配。我也知道,大多数用户不会遇到这个异常,但是在我的崩溃日志中,偶尔会看到一些用户遇到了这个问题。你有什么想法吗?authenticator.xml文件是否可以通过某种方式进行修改以导致这个问题出现? - shoke
3
@clu,你是否解决了你的问题?我遇到了完全相同的情况。这个错误只会在一小部分用户的设备上出现,主要是HTC One X、HTC One SV和HTC Desire 500,还有其他一些设备也会出现这种情况。 - chandsie
1
@chandsie 我也是。只有HTC设备似乎有这个问题。对于其他设备,它都可以正常工作。 - Kiran Kumar
我遇到了这个问题。@clu,你能解决这个问题吗? - Reshad
显示剩余2条评论

25

在我的情况下,问题非常简单,就是在res/xml/authenticator.xml中声明的android:accountType="com.foo"与创建帐户时错误地引用为"foo.com"造成了不匹配。

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

糟糕!


1
嗨,在我的情况下,xml中的accountType和newAccount对象中的accountType是相同的。但仍然显示caller uid XXXX与认证器的uid不同的错误。为什么? - Vijay Vankhede

10

有几个部分需要实现自定义账户...

要在您的Activity中调用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字符串相同!

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

最后,您需要在清单文件中定义您的服务。请不要忘记相关权限以管理您的账户(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>

小心打错字!AuthenticaTAtionService。而且实际上它的名称是“name =”.AuthenticationService”(带有一个点),在我的情况下显示为红色,但它仍然可以工作。 - FlorianB

5

我的错误在于假设AccountManager的getAccounts()方法只返回与我的应用程序上下文相关联的帐户。 我更改为

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

为了

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

4
同样的错误也会出现在您的清单中的intent-filters中放入不正确的值。 我按照android-dev教程上的同步适配器设置了“intent-filter/action android:name”以及syncadapter/accountauthenticator的“meta-data/android:name”的伪值。 这个错误导致相同的错误出现在日志中。
记录一下,正确的值是:{android.content.SyncAdapter, android.accounts.AccountAuthenticator}。

2
在我的情况下,问题出在清单文件中的权限设置。我已经解决了。
<uses-permission android:name="ANDROID.PERMISSION.GET_ACCOUNTS"/>

当我把它改成小写字母时,原来的所有字母都变成了小写字母。

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

问题得到解决。

2

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

例如,如果您的模块名称是

com.example.module.auth

您的服务android:name应该为

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

在 AndriodManifest.xml 中


2

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

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

导致这个错误的原因。希望能对某些人有所帮助!


1
这里有另一种可能的解决方案。
当我的用户使用与他的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;
}

你可以调用 accountManager.getAccountsByType("myservice.com") - nickgrim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接