Android:HttpsUrlConnection with Authenticator for Basic Authentication 在密码错误时永远迭代(在 401 响应中)

标签 android httpurlconnection http-status-code-401

我通过使用 Authenticator 并设置默认的 Authenticator 对象来使用具有基本身份验证的 HttpsUrlConnection,如下所示:

Authenticator.setDefault(new Authenticator() {
    protected PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication("user", "userpass"
            .toCharArray());
    }
});

当我访问我的网络服务时,连接会调用我的 getPasswordAuthentication() 方法来获取凭据并将其发送到网络服务器。只要密码正确,这就可以正常工作。 :)

但是,恰好有人在网络服务器上更改了基本认证密码,然后我的请求没有返回。

我对其进行了调试,结果是我对 getInputStream() 的调用从未返回。 HttpsUrlConnection 确实收到 401 响应,并通过再次获取相同的凭据在内部对此使用react。但由于我只提供了一个用户和密码,这将再次失败(又一次......)。

所以我的问题是:我怎样才能防止这种情况发生,哪里有一个钩子(Hook)来对错误的密码使用react(分别是 401 响应),以便我可以显示适当的错误消息并取消请求?

以下是在 HttpsUrlConnection 上重复调用的方法的堆栈跟踪摘录:

1: MyOwnHttpConnection$3.getPasswordAuthentication() line: 99   
2: Authenticator.requestPasswordAuthentication(InetAddress, int, String, String, String) line: 162  
3: HttpsURLConnectionImpl$HttpsEngine(HttpURLConnectionImpl).getAuthorizationCredentials(String) line: 1205 
4: HttpsURLConnectionImpl$HttpsEngine(HttpURLConnectionImpl).processAuthHeader(String, String) line: 1178   
5: HttpsURLConnectionImpl$HttpsEngine(HttpURLConnectionImpl).processResponseHeaders() line: 1118    
6: HttpsURLConnectionImpl$HttpsEngine(HttpURLConnectionImpl).retrieveResponse() line: 1044  
7: HttpsURLConnectionImpl$HttpsEngine(HttpURLConnectionImpl).getInputStream() line: 523 
8: HttpsURLConnectionImpl.getInputStream() line: 283    

最佳答案

我通过将请求/响应逻辑抽象到 MyRequest 类中解决了这个问题。这允许我有一个请求范围的变量,它可以告诉我的 Authenticator 是否应该使用指定的用户名和密码发出请求,或者是否应该停止重试(通过返回 null)。它看起来有点像下面(考虑这个伪代码)

public class MyRequest
{
    private boolean alreadyTriedAuthenticating = false;
    private URL url;

    ...

    public void send()
    {
        HttpUrlConnection connection = (HttpUrlConnection) url.openConnection();
        Authenticator.setDefault(new Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
                if (!alreadyTriedAuthenticating)
                {
                    alreadyTriedAuthenticating = true;
                    return new PasswordAuthentication(username, password.toCharArray());
                }
                else
                {
                    return null;
                }
            }
            InputStream in = new BufferedInputStream(connection.getInputStream());

            ...

    }
}

关于Android:HttpsUrlConnection with Authenticator for Basic Authentication 在密码错误时永远迭代(在 401 响应中),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7808301/

相关文章:

java - 应用程序崩溃 android Activity t40}}} 超时

java - 如何通过 URL 和 HttpURLConnection 类在请求正文中添加对象

java - 在正文中使用 application/x-www-form-urlencoded 的 400 错误白色 Java Post

eclipse - 使用 Eclipse 插件进行 AppEngine 部署期间出现错误 401 未经授权(无效的 OAuth token )

javascript - 是否可以监听所有 Ajax 调用?

asp.net-mvc - 无法通过本地 IIS 进行 Windows 身份验证

android - frida hook 本地非导出函数

android - 不使用静态图像时避免 Android 内存泄漏

java - 测试的 Gradle 依赖项与编译的不同

java - 从 java(图像和一些参数)发送表单数据,如 curl