slider

还是菜鸟
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

received authentication challenge is null

Posted on 2012-07-16 16:29  slider  阅读(1891)  评论(0编辑  收藏  举报

  这个问题是我在登录注册的时候出现的。Android客户端与DJANGO后台。我每次输入错误密码的时候就会出现上述错误,而输入正确的用户名密码是没有这个错误的。还有一个奇怪的现象:我写一个java测试代码的时候,输入错误的用户名和密码是不会抛出这个异常的,而我把该代码转移到Android程序里面,就会出现这个异常。真实让人费解。。。。

  查了下源码发现HttpURLConnectionImpl.java,使用httpurlconnection请求http,有两种状态下会抛出这个异常:

/**
     * React to a failed authorization response by looking up new credentials.
     */
    private Retry processAuthHeader(String responseHeader, String retryHeader) throws IOException {
        // keep asking for username/password until authorized
        String challenge = this.responseHeader.get(responseHeader);
        if (challenge == null) {
            throw new IOException("Received authentication challenge is null");
        }
        String credentials = getAuthorizationCredentials(challenge);
        if (credentials == null) {
            return Retry.NONE; // could not find credentials, end request cycle
        }
        // add authorization credentials, bypassing the already-connected check
        requestHeader.set(retryHeader, credentials);
        return Retry.SAME_CONNECTION;
    }
/**
     * Returns the retry action to take for the current response headers. The
     * headers, proxy and target URL or this connection may be adjusted to
     * prepare for a follow up request.
     */
    private Retry processResponseHeaders() throws IOException {
        switch (responseCode) {
            case HTTP_PROXY_AUTH: // proxy authorization failed ?
                if (!usingProxy()) {
                    throw new IOException(
                            "Received HTTP_PROXY_AUTH (407) code while not using proxy");
                }
                return processAuthHeader("Proxy-Authenticate", "Proxy-Authorization");

            case HTTP_UNAUTHORIZED: // HTTP authorization failed ?
                return processAuthHeader("WWW-Authenticate", "Authorization");

            case HTTP_MULT_CHOICE:
            case HTTP_MOVED_PERM:
            case HTTP_MOVED_TEMP:
            case HTTP_SEE_OTHER:
            case HTTP_USE_PROXY:
                if (!getInstanceFollowRedirects()) {
                    return Retry.NONE;
                }
                if (requestBodyOut != null) {
                    // TODO: follow redirects for retryable output streams...
                    return Retry.NONE;
                }
                if (++redirectionCount > MAX_REDIRECTS) {
                    throw new ProtocolException("Too many redirects");
                }
                String location = getHeaderField("Location");
                if (location == null) {
                    return Retry.NONE;
                }
                if (responseCode == HTTP_USE_PROXY) {
                    int start = 0;
                    if (location.startsWith(url.getProtocol() + ':')) {
                        start = url.getProtocol().length() + 1;
                    }
                    if (location.startsWith("//", start)) {
                        start += 2;
                    }
                    setProxy(location.substring(start));
                    return Retry.NEW_CONNECTION;
                }
                URL previousUrl = url;
                url = new URL(previousUrl, location);
                if (!previousUrl.getProtocol().equals(url.getProtocol())) {
                    return Retry.NONE; // the scheme changed; don't retry.
                }
                if (previousUrl.getHost().equals(url.getHost())
                        && previousUrl.getEffectivePort() == url.getEffectivePort()) {
                    return Retry.SAME_CONNECTION;
                } else {
                    // TODO: strip cookies?
                    requestHeader.removeAll("Host");
                    return Retry.NEW_CONNECTION;
                }

            default:
                return Retry.NONE;
        }
    }

  说到这里,也间接说明一个前提条件,请求失败返回的是401错误,故响应头必须添加上”WWW-Authenticate“即可解决这个问题