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



Answers

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

[...]如果您发现来自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" ... />

其次,如果你像我一样想将样本嵌入到现有的应用程序中进行测试,那么请确保使用属于此示例但不属于android.provider.SyncStateContract包的一部分的Constants类。 因为这两个类都使用创建Account对象时使用的相同属性名称ACCOUNT_TYPE

Question

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

所以我会在这里记下我的解决方案 ,以防其他人遇到同样的问题。




在我的情况下,它是清单文件中的权限

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

这是全部大写,当我改变它

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

问题消失了




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

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




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

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




有几个部分可以实现自定义帐户...

要在您的活动中调用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 / 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>



还要确保您的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>



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

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




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

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

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

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

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



Related



Tags

android android