如何响应Android中的HTTP身份验证挑战

Gro*_*ppe 7 authentication https android http

在我的应用程序中,我通过HTTPS对Web服务进行HTTP调用.我的愿望是设计我的客户端,以便在有身份验证挑战时只询问用户的用户名和密码.我想要被动,而不是先发制人.由于我的应用程序的性质,在某些情况下,它不需要进行身份验证.

在iOS中,通过NSURLConnectionDelegateProtocol非常容易地完成此过程,该程序在我的应用程序的iOS版本中实现.使用此类建立连接,并且仅当提出质询时,类才会向其委托询问身份验证凭据.

如何在Android中完成?使用AuthenticationHandler?或者也许是认证者?如果是这样,可以提供示例或教程吗?

编辑1:

使用Authenticator类(请参阅下面的答案)我现在能够响应身份验证挑战,但目前只能使用硬编码凭据.我想提示用户输入用户名和密码.根据Android文档,在该getPasswordAuthentication方法中,您"通常会提示用户输入所需内容".

这怎么可能?在不阻塞UI线程的情况下,我知道不能/不应该这样做,如何在该方法中显示对话框,等待用户输入,然后检索输入的凭据并返回它们?

编辑2:

虽然使用Authenticator类很少或没有示例,但我能够找到的建议是,在单个方法中提示用户输入是不可能的,例如getPasswordAuthentication.可能必须恢复到Apache Http客户端......

最终编辑:

我仍在使用HttpURLConnection,但是按照爱德华在下面提出的建议行事.似乎没有任何可配置的类来处理身份验证挑战并提示用户输入,所以我手动执行此操作.

Edw*_*alk 4

发送不带身份验证标头的请求。如果需要身份验证,连接将失败并出现 401 错误。让失败返回到发出初始请求的任何代码。然后,该代码应该向用户显示一个身份验证对话框。记住用户提供的用户名/密码,然后重试失败的请求,并将必要的身份验证标头添加到请求中。

请记住会话其余部分的用户名/密码,这样您就不必一直询问用户。

很抱歉我没有任何示例代码;我已经在 java.net 中实现了这个,但是如果您使用 apache,这对您没有任何好处。

这个线程可能会帮助你:Http Basic Authentication in Java using HttpClient?

编辑:

我已经在 java.net 中实现了这个,但这是我受雇的工作,我无权访问源代码。一个问题是 java.net 不允许您在每个连接的基础上设置身份验证,而是让您实现一个全局身份验证器。由于我的应用程序仅与一个特定网站进行通信,因此这不是问题。

我所做的是创建Authenticator的子类,用于缓存用户的用户名/密码数据。缓存的初始值为空。还有一个“尝试计数器”。当调用身份验证器并且没有缓存的用户/密码信息时,系统会通过对话框提示用户。如果存在缓存值,则会返回它们,而不会打扰用户。

如果后续调用身份验证器,则假定用户/密码信息不正确,并再次提示用户。如果计数器达到 10,则验证器返回 null(失败)。

在每次新的互联网连接之前都会重置计数器。

更智能的身份验证器会关注主机和/或领域(提示字符串)并相应地缓存用户/密码。

我不确定这些在 Android 环境中对您是否有用,因为弹出对话框可能不是您的身份验证器的可用选项。但我的想法可能是错的;这取决于您的应用程序。

在 Android 环境中,您需要从线程执行 http 请求,然后在数据到达时向活动发出信号。如果您的线程检测到 401 错误,它会向 Activity 发出该结果的信号,然后 Activity 可能会弹出一个对话框并重新启动线程。然后,该线程将注册一个简单的身份验证器,该身份验证器仅返回用户/密码信息。或者,线程可以手动构建授权标头,尽管这需要更多工作。