SecurityException:呼叫者uid XXXX与验证者的uid不同


84

尝试实施Sample Sync Adapter应用程序时收到上述异常。我已经看到许多与此问题相关的帖子,但没有令人满意的答复。

因此,如果有人遇到同样的问题,我将在这里写下我的解决方案


谢谢。我遇到了这个问题,由于您的帖子,我能够更快地找到解决方案。
Damian

4
不幸的是,与此同时,发布的链接已损坏。有人有其他选择吗?
johsin18年

Answers:


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对象时相同的属性名称。


谢谢!您的第一笔支票已解决了问题。猜猜是什么,在一个新项目中,我忘记了所有关于Authenticator xml文件的信息。
George Pligoropoulos

7
我仍然看到此问题,但仅适用于部分用户。我已经仔细检查了authenticator.xml文件中的android:accountType是否与我的GenericAccountsService中的常量匹配。我也知道绝大多数应用程序用户都不会发生此异常,但是在我的崩溃日志中,我偶尔会看到少数用户崩溃的情况。任何的想法?可以以某种方式修改authenticator.xml文件导致此问题吗?
b.lit 2014年

3
@clu您是否能够解决您的问题?我正面临着相同的情况。这个错误只会在我的一小部分用户中浮现:主要是在HTC One X,HTC One SV和HTC Desire 500上,以及许多其他设备上。
chandsie

1
@chandsie这里也是。仅HTC设备似乎有此问题。它对其他所有设备都适用。
Kiran Kumar 2015年

@clu我也面临着同样的问题。您是否能够解决此问题或找到其根本原因?
wasaig '16

25

在我的情况下,问题很简单,就是在res/xml/authenticator.xmlas中声明的accountType不匹配,android:accountType="com.foo""foo.com"在创建Account时引用不正确:

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

h!


1
嗨,就我而言,xml和newAccount对象中的accountType都是相同的。仍然显示呼叫者uid XXXX与验证者的uid错误不同。为什么?
维杰·凡赫德

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相同的字符串!

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

提防TYPO!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

如果您在清单的意图过滤器中输入了不正确的值,则会出现相同的错误。我浏览了有关同步适配器的android-dev教程,并最终为“意图过滤器/操作android:name”和“ meta-data / android:name”为syncadapter / accountauthenticator设置了虚假值。此错误导致相同的错误出现在日志中。

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


2

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

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

com.example.module.auth

您正在使用android:name应该是

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

在AndriodManifest.xml中


2

首先,再看一看Jan Berkel的出色调试建议。

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

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

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

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

<application>的子项!为我做到了,谢谢!它是<service android:name =“。AuthenticationService”>
FlorianB

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

这是导致此错误的原因。希望这对某人有帮助!


2

就我而言,这是我拥有的清单文件中的权限

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

都是大写字母,当我将其更改为

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

问题消失了


1

也,

检查您是否将AccountType像普通的旧字符串一样对待。

我的大部分代码都打包在com.mycompany.android下

我一直在成功使用以下AccountType:com.mycompany.android.ACCOUNT

现在,我希望使用多个帐户,并且当我尝试在帐户末尾附加“ .subType”的方法时,由于

呼叫者uid xxxxx与验证者的uid不同

但是,如果我使用“ _subType”(下划线而不是dot),则可以正常工作。

我的猜测是,Android试图将com.mycompany.android.ACCOUNT视为合法的程序包名称,但事实并非如此。

因此,再次:

BAD com.mycompany.android.ACCOUNT.subType

良好com.mycompany.android.ACCOUNT_subType


1

如果遇到此错误,则以上所有解决方案均不适合您。同样,您假定您已遵循所有过程。身份验证服务可能是由其他开发人员开发的,您想利用它来添加帐户。

您可以尝试使用发布密钥库对应用程序进行签名。现在,您运行该应用程序。我想这应该对您有用。


1

这是另一种可能的解决方案。

当我的用户使用与他的Android Google帐户相同的电子邮件在我的应用程序中注册时,出现了此错误。

因此,当我尝试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 '16

0

还要确保您的AccountAuthenticatorService具有证明者意图过滤器;

即。

<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

如果相同的应用程序来自不同的商店,例如亚马逊应用程序商店和Google Play商店,则最终会抛出安全异常,因为在这种情况下,应用程序的签名会有所不同。登录,任何一个应用程序都将崩溃。我曾经遇到过这个麻烦。尤其是亚马逊应用程序商店会出于安全目的使用自己的签名对其应用程序进行签名。

注意:如果这里没有输入错误或其他答案,请在单次登录的情况下检查应用程序的签名。


0

对于仍然遇到问题的用户:https ://stackoverflow.com/a/37102317/4171098

就我而言,我不小心在<application>代码外的清单中定义了AuthenticatorService 。将声明移入内部 <application>可解决此问题。希望会帮助某人。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.