2011年2月10日木曜日

Account Managerを利用したアカウント登録について(失敗)

Account Managerについて調べる中で、
プログラムからアカウントが自動登録できないか挑戦してみました。

http://developer.android.com/reference/android/accounts/AccountManager.html#addAccountExplicitly(android.accounts.Account, java.lang.String, android.os.Bundle)

このaddAccountExplicitlyと既存のアカウント、PWがあればいけるか?
と思いManifestにAUTHENTICATE_ACCOUNTSを追加してやってみたのですがSecurity Exception発生。
呼び出し元のアプリのUidが権限ありませんよ、とのこと。
ちなみに今回のアカウントはGoogleアカウント。

ソースをたどるとこんな感じ。
frameworks/base/core/java/android/accounts/AccountManager.java



482     public boolean addAccountExplicitly(Account account, String password, Bundle userdata) {
483         if (account == null) throw new IllegalArgumentException("account is null");
484         try {
485             return mService.addAccount(account, password, userdata);
486         } catch (RemoteException e) {
487             // won't ever happen
488             throw new RuntimeException(e);
489         }
490     }


mServiceはIAccountManagerのインスタンス。

79 public class AccountManagerService
80         extends IAccountManager.Stub
81         implements RegisteredServicesCacheListener<AuthenticatorDescription> {


そして、ソースを追ってAccountManagerServiceへ、


/frameworks/base/core/java/android/accounts/AccountManagerService.java
AddAccountメソッド


387     public boolean addAccount(Account account, String password, Bundle extras) {
388         if (account == null) throw new IllegalArgumentException("account is null");
389         checkAuthenticateAccountsPermission(account);
390
391         // fails if the account already exists
392         long identityToken = clearCallingIdentity();
393         try {
394             return insertAccountIntoDatabase(account, password, extras);
395         } finally {
396             restoreCallingIdentity(identityToken);
397         }
398     }

checkAuthenticateAccountsPermissionメソッド


1882     private void checkAuthenticateAccountsPermission(Account account) {
1883         checkBinderPermission(Manifest.permission.AUTHENTICATE_ACCOUNTS);
1884         checkCallingUidAgainstAuthenticator(account);
1885     }



Manifestのチェックと,Uidのチェック


checkCallingUidAgainstAuthenticatorメソッド

1838     private boolean hasAuthenticatorUid(String accountType, int callingUid) {
1839         for (RegisteredServicesCache.ServiceInfo<AuthenticatorDescription> serviceInfo :
1840                 mAuthenticatorCache.getAllServices()) {
1841             if (serviceInfo.type.type.equals(accountType)) {
1842                 return (serviceInfo.uid == callingUid) ||
1843                         (mContext.getPackageManager().checkSignatures(serviceInfo.uid, callingUid)
1844                                 == PackageManager.SIGNATURE_MATCH);
1845             }
1846         }
1847         return false;


serviceInfoに格納されているuidと呼び出し元のuidが同一かどうかチェックしています。
自家製のアプリではuidが同じではないので、Security Exception発生という流れ。

自前サービスのアカウントならいけるのか?というのは今後の検討。

0 件のコメント:

コメントを投稿