帐户管理器中的用户数据可由其他应用程序访问

问题描述:

我试图利用Android的帐户管理器来存储用户的应用程序凭证。 虽然我没有保存用户的密码,但我想将其他安全密钥保存到帐户的UserData中。根据下面引用的文档,这不应该被具有不同UID的应用程序访问。帐户管理器中的用户数据可由其他应用程序访问

公共字符串getUserData(客户账户,串键)

获取与该账户相关联的“钥匙”命名的用户数据。这是用于验证器和相关代码以将任意元数据与帐户一起存储。密钥和值的含义取决于帐户的身份验证器。

从主线程调用此方法是安全的。

此方法要求调用方持有权限AUTHENTICATE_ACCOUNTS并具有与帐户的身份验证器相同的UID。

参数 责任 - 查询 返回 的用户数据,空用户数据,如果帐户或键不存在

为了测试这个帐户,我创建了创建应用程序一个帐户并将一些内容保存到UserData。我还创建了另一个访问第一个应用程序帐户的应用程序。下面是摘录:

的第一APP:

AccountManager am = (AccountManager) context.getSystemService(Context.ACCOUNT_SERVICE); 
final Account account = new Account("Account Name", "my.account.type"); 
am.addAccountExplicitly(account, null, null); 
am.setAuthToken(account, "my.account.type", "some auth token"); 
am.setUserData(account, "key.for.secure.user.data", "some secure data"); 

第二应用:

AccountManager am = (AccountManager)context.getSystemService(Context.ACCOUNT_SERVICE); 
Account[] accountsFromFirstApp = am.getAccountsByType("my.account.type"); 
for(Account acct: accountsFromFirstApp){ 
    printToLogs(acct.name); 
    printToLogs(am.getUserData(acct, "key.for.secure.user.data")); 
} 

基于文档上面,我预计第二应用的getUserData()返回一个例外没有与所有者应用程序相同的UID。令人惊讶的是,我能够访问第一个应用程序的用户数据,没有错误。

但是,当我试图通过使用“com.google”作为accountType从谷歌访问帐户,我得到了预期的异常。

我的实施出了什么问题?我错过了Android的文档中没有提到的一些配置吗?任何帮助将非常感激。

关于第二个想法,如果这些用户数据可以轻松访问(假设其他应用程序知道我的应用程序的帐户类型),那么将UserData中的字符串存储在SharedPreferences中的区别是什么?

+0

您正在使用哪个android版本?您是否使用不同的签名证书以releasemode编译了这两个应用程序?你的应用清单是否包含[manifest android:sharedUserId](http://developer.android.com/guide/topics/manifest/manifest-element.html#uid)?这两个应用程序有不同的[manifest packagename](http: //developer.android.com/guide/topics/manifest/manifest-element.html#package)? – k3b 2015-03-19 07:33:42

+0

在测试的时候,我使用了几个android版本,例如KitKat和JellyBean的变体。我还没有尝试在发布模式下编译它们。我没有指定android:sharedUserId,我确定他们有不同的UID,因为我也将它们放在日志中。他们也有不同的软件包名称。 – Dynameyes 2015-03-19 14:27:36

+0

现在我重新阅读答复,如果我使用不同的签名证书回答k3b的问题,我没有。它实际上是我用来测试这个的调试证书。但文档没有提到这件事。它真的很重要吗? – Dynameyes 2015-03-19 15:23:52

从文档的AccountManager:

这个类提供访问用户的在线账户的集中注册。用户每个帐户输入一次凭据(用户名和密码),通过“单击”批准授予应用程序访问在线资源的权限。

由AccountManager管理的账户是集中且可重复使用的,例如,所有Google应用都可以使用同一个帐户,并非所有应用都必须创建自己的Google帐户。

因此,据我所知,AccountManager的想法之一就是拥有可重复使用的帐户,可以从不同的应用访问。

但是由于存储的凭证可以从不同的地方访问,因此您不应该在AccountManager中存储任何纯文本密码。

这个主题是否适合您:What should I use AccountManager for?

+0

感谢您的回复!我想这个答案是我最后一个关于使用AccountManager而不是SharedPreferences的优点的问题。虽然我理解你说的这个想法,但我主要关心的是账户管理器方法没有返回与AccountManager.documentation中声明的相反的异常。有任何想法吗? – Dynameyes 2015-03-19 14:32:52

+3

也许是因为你使用调试密钥库对它们进行了签名?我目前没有其他想法... – 2015-03-20 07:50:17

+0

我测试了sames和differents keystore应用程序。所以我确认托马斯的答案是对的。 使用不同的keystore你不会得到异常,但AccountManger的getAccountsByType()返回一个空数组。 – smora 2016-01-02 17:03:19