2010-09-22 78 views
83

嘗試實施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

回答

41

首先,檢查條件對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

53

一些其他有用的技巧來調試這樣的問題。

首先啓用詳細日誌記錄的一些標籤:

$ 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" 
1

此外,

檢查,看看你是太多治療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

5

我的錯誤是假設的AccountManager getAccounts( )方法返回的帳戶只與我的應用程序上下文關聯。我從

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

改爲

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

確保您的服務XML指向正確的位置。

舉例來說,如果你的模塊名稱是

com.example.module.auth

你的Android服務:名稱應該是

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

.xml

0

還要確保您的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> 
10

有實現自定義帳戶幾部分組成?

要在活動調用的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

24

在我的情況下,問題很簡單地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

4

如果您在清單中的意圖過濾器中輸入了不正確的值,則會出現相同的錯誤。 我經歷了關於同步適配器的android-dev教程,並最終爲syncadapter/accountauthenticator設置了「intent-filter/action android:name」以及「meta-data/android:name」的僞造值。這個錯誤導致了相同的錯誤出現在日誌中。

爲了記錄在案,正確的價值觀是:{android.content.SyncAdapter,android.accounts.AccountAuthenticator}

2

首先,再看看揚伯克爾出色的調試建議。

最後,要檢查的另一件事是您的內容提供商和身份驗證以及同步服務聲明爲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

1

如果您遇到此錯誤,並且上述所有解決方案均無法爲您工作,另外,你還假定你已經遵循了所有的程序。身份驗證服務可能由其他開發人員開發,您希望使用它來添加帳戶。

您可以嘗試的是嘗試使用發行密鑰庫對您的應用程序進行簽名。現在你運行該應用程序。我想這應該適合你。

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

在我的情況下,它是在manifest文件 權限,我有

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

它是全部大寫,當我把它改成

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

問題不見了

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

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

+0

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

0

如果你得到這個異常的三星設備確保您不使用safe mode

0

如果相同的應用程序來自不同的商店,例如amazon應用程序商店和谷歌Play商店,最終會拋出安全性異常,因爲這種情況下應用程序的簽名會有所不同。如果您計劃使用相同的身份驗證器單點登錄的目的,任何一個應用程序都會崩潰。我曾遇到過這個麻煩。尤其是亞馬遜應用商店會出於安全考慮而對自己的應用程序進行簽名。

注:如果沒有錯字的錯誤或這裏提到的其它一些問題,請檢查該應用程序的簽名單點登錄的情況下,

0

對於那些誰仍然expierienced問題:https://stackoverflow.com/a/37102317/4171098

在我的情況下,我無意中在<application>標籤之外的Manifest 中定義了AuthenticatorService。移動內部的聲明 <application>修復了這個問題。希望會幫助別人。