1

基本認証で保護されたサーバーにアクセスしようとすると、最初の要求は常に失敗しますが、2 番目の要求は同じ資格情報で成功します。

関連するメソッドは次のとおりです。

// username and password are entered by the user, the serviceurl is the endpoint on the server
private boolean testHttpLogin(String username, String password, String serviceUrl) {
  if (username != null && username.length() > 0 && password != null && password.length() > 0) {
    try {
        Response<String> serverResponse = null;
        serverResponse = Ion.with(getApplicationContext()).load(serviceUrl).noCache()
                            .basicAuthentication(username, password)
                            .asString().withResponse().get();
        logger.debug("response in testLogin: " + serverResponse.getResult());
        int responseCode = serverResponse.getHeaders().code();
        if (responseCode != HttpURLConnection.HTTP_UNAUTHORIZED) {
            taskUserName = username;
            taskPassword = password;
            logger.info("Login successful!");
            return true;
        } else {
            logger.info("Login failed!");
            BasisUtils.showToast("User not authorized!");
        }
    } 
    catch (ExecutionException | InterruptedException e) {
        [...] // handle exceptions...   
    }       
    return false;
  }
}

したがって、ユーザーがログインしようとすると、最初は「許可されていません」として返され、2 回目に (入力を変更せずに) 試行すると機能します。

私がすでに試したこと:

  • 認証されていないリクエストを最初に送信し、認証されたリクエストを 2 番目に送信する
  • 最初に間違った資格情報で認証済みリクエストを送信する
  • 2 番目のリクエストを送信する前に 0.5 秒待機します
  • Ion によるキャッシュの有効化/無効化

最初のリクエストのレスポンス ヘッダーは次のとおりです。

Date: Fri, 12 Jun 2015 13:00:00 GMT 
Server: Apache
WWW-Authenticate: Basic realm="somerealm"
Content-Length: 381
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=iso-8859-1

成功したログインのヘッダーは次のようになります。

date: Fri, 12 Jun 2015 14:28:15
server: Apache
x-powered-by: ASP.NET
x-aspnet-version: 2.0.50727
x-xss-protection: 1; mode=block
x-frame-options: SAMEORIGIN
cache-control: private, must-revalidate, max-age=0
content-type: text/html;charset=utf-8
set-cookie:[the token I need]; Expires=Fri, 12-Jun-2015 14:29:12 GMT; Path=/path/on/server; HttpOnly
vary: Accept-Encoding
content-encoding: gzip
content-length: 1689
keep-alive: timeout=15, max=98

アップデート

リクエスト ヘッダーは次のようになります。

Host: mobile.myserver.com:4434
User-Agent: Dalvik/1.6.0 (Linux; U; Android 4.1.2; GT-P5100 Build/JZO54K)
Accept-Encoding: gzip, deflate
Connection: keep-alive
Accept: */*
Cache-Control: no-cache
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ= // exchanged the real credentials against username:password

どちらのリクエストでも同じです。

今日ヘッダーを確認したところ、サーバーへの以前の接続のヘッダーに Cookie が含まれていることに気付きました (ユーザーがログインする前に、サーバーの認証方法を確認する必要があります)。リクエストを行う前にすべての Cookie を削除するようになりました (Cookie がリクエストに対して有効でない場合に備えて):

Ion.getDefault(getApplicationContext()).getCookieMiddleware().getCookieStore().removeAll();
serverResponse = Ion.with(getApplicationContext()).load(serviceUrl).noCache()
                    .setLogging("ION VERBOSE", Log.VERBOSE).basicAuthentication(username, password)
                    .asString().withResponse().get();

もう少し調べただけで、さらに混乱します。どうやら、2 番目の要求は同じ「アプリ セッション」にある必要さえありません (つまり、設定を介してアプリを強制停止し、再度開いても、要求は引き続き成功します)。

4

0 に答える 0