(三)高级篇____4、记住用户——创建一个自定义的账户类型
原文链接:http://docs.eoeandroid.com/training/id-auth/custom_auth.html
作者:zachgenius
完成时间:2012-8-30
目录[隐藏] |
创建一个自定义帐户类型
到目前为止我们已经讨论了如何访问Google API,它使用由谷歌定义的账户和用户。如果你有自己的线上服务,而它却没有谷歌账户或用户,那么你将如何做?其实可以相对直接地在用户设备上安装一个新的账户类型。这节课解释如何创建一个和内建账户一样能工作的自定义帐户类型。
实现你的自定义帐户代码
首先你需要一种获取用户凭据的方法。这有可能像一个询问用户名和密码的对话框一样简单。或者它可能是一个更奇特的程序,比如一次性密码或生物识别扫描。无论哪种方法,你有责任去实现这些需求:
1. 收集用户凭据 2. 在服务器上验证这些凭据 3. 在设备商保存凭据
通常情况下,以上三个需求都可以在一个activity中处理。我们称之为“验证者activity”。
因为他们都需要和账户管理(AccountManager)系统进行相互作用,因此验证者activity就会有一些一般activity所没有的特定需求。为了方便地把事情做好,Android框架提供了一个基础类,AccountAuthenticatorActivity,通过它你可以专注去创建你自己的自定义身份验证。
至于如何处理验证者activity的前两个需求,即凭证收集和验证,这完全取决于你。(如果假定只有一种方法来实现它,那么很显然我们就没必要去做“自定义”账户类型。)第三个需求有一个典型的,而且颇为简单的实现方式:
final Account account = new Account(mUsername, your_account_type); mAccountManager.addAccountExplicitly(account, mPassword, null);
对安全更注意一些
理解AccountManager 不是一种加密服务或者密钥链这件事非常重要。它仅仅按照你传递的内容用明文来存储。在大部分设备上,这不是一个典型的顾虑,因为设备把他们存储在只有根用户才能访问的数据库中。但是在已经被Root过的设备上,通过adb连接可以让任何人读取凭据信息。
因此,你不能直接传递用户的真实密码给android.os.Bundle) AccountManager.addAccountExplicitly()。 相反,你应该存储加密的安全令牌来保障限制攻击者的使用。如果你的用户凭证需要保护一些敏感信息,你应该谨慎考虑做出相似的事情。
记住: 当涉及到安全有关代码,请按照“流言终结者(Mythbusters)”规则:不要在家里尝试这个!在执行任何自定义代码之前请一定要咨询安全专业人士。
既然安全免责声明是不合适的,那么现在是时候回去工作了。你已经理解了自定义帐户代码的核心,剩下的就是去实现它了。
继承AbstractAccountAuthenticator
为了让AccountManager能够和你的自定义用户账户代码一起工作,你需要一个实现了AccountManager所需要的接口的类。这个类就是“验证类”(authenticator class)。
建立一个验证类的最简单的方法是继承AbstractAccountAuthenticator并且实现其中的抽象方法。如果你已经学习了之前的课程,AbstractAccountAuthenticator的抽象类方法可能看起来比较熟悉:他们的功能刚好与你在前一课中调用的账户信息和授权令牌的方法相反。
正确地实现一个验证类要求一连串单独的代码段。首先,AbstractAccountAuthenticator 有七个你必须重写的抽象方法。其次,你需要在你的application menifes(将在下一节讲到)中为"android.accounts.AccountAuthenticator"添加一个intent filter。最后,你必须提供两个XML资源,其中包括你的自定义帐户类型的名称和系统将在这个类型账户后面显示的图标。
你可以查找一个“一对一向导”来实现一个成功的验证类和在AbstractAccountAuthenticator文档中的XML文件。同样在SampleSyncAdapter示例程序中有一个简单的实现方法。
如果你已读过SampleSyncAdapter的代码,你就会发现有很多个方法在一个bundle钟返回一个intent。而这个intent和将被用于运行你的自定义的验证activity的是同一个intent。如果你的验证activity需要任何特殊的初始化参数,你可以使用Intent.putExtra()来将他们添加进该intent中。
创建一个验证服务
既然你已经有了一个验证类,你需要一个地方来让它运行。账户验证在多个应用中必须是可用的,并且能够在后台运行,所以他们自然需要运行在一个服务Service中。我们称之为验证服务。
你的验证服务一定要非常简单。它需要做的仅仅是在onCreate()方法中创建一个你的验证类的实例,并且调用getIBinder()和onBind()方法。SampleSyncAdapter示例程序中有一个很好的验证服务的例子。
不要忘记在你的manifest文件中添加一个<service>标签和一个AccountAuthenticator intent的intent filter(过滤器),并且声明这个账户验证器:
<service ...>
<intent-filter>
<action android:name="android.accounts.AccountAuthenticator" />
</intent-filter>
<meta-data android:name="android.accounts.AccountAuthenticator"
android:resource="@xml/authenticator" />
</service>
发布你的服务
你已经完成了!系统现在可以在那些大牌账户类型比如"Google"和"Corporate"当中认出你的账户类型。你可以使用Accounts & Sync(账户与同步)设置页面来添加一个账户,而且那些需要你自定义类型的账户的软件能够像任何其他账户类型一样美剧和验证你的账户类型。
当然,这些全都是假设你的账户服务被正确的安装在设备上的。如果只有一个程序需要访问这个服务,那么就这就会很简单,只需要在应用中捆绑这个服务就可以了。但是如果你想让你的账户服务被用于不止一个应用,那么事情就会变得棘手了。因为你不想把服务绑定到每一个的应用上,并且在设备上占用大量的空间来保存多个副本。
一种解决方法把这个服务换成一个小的,有特殊目的的APK。当一个应用想要使用你的自定义帐户类型,它可以检查这个设备看你的自定义帐户类型有没有运行。如果没有,它能够带领用户到Google Play下载这个服务。这刚开始看起来似乎是一个大麻烦,但是同让每一个应用程序在使用自定义账户类型时重复输入凭据的方案对比来看,这很显然要简单得多。

浙公网安备 33010602011771号