6

Apache HttpClient Java ライブラリを使用して、フォームベースの認証 (facebook.com など) を使用する Web サイトに対して自分自身を認証しようとしています。
このウェブサイトのプログラムを主な例として使用します: http://www.elitejavacoder.com/2013/10/http-client-form-b​​ased -authentication.html 、私はそれを行うことができました - しかし、私がしたことがいくつかありますこのプログラムについて理解していません。コードは次のとおりです。

package com.elitejavacoder.http.client;

import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.params.ClientPNames;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

public class HttpClientFormAuthentication {
    public static void main(String[] agrs) {
        String host = "yourhostname.com";
        int port = 8080;
        String protocol = "http";

        DefaultHttpClient client = new DefaultHttpClient();

        try {
            HttpHost httpHost = new HttpHost(host, port, protocol);
            client.getParams().setParameter(ClientPNames.DEFAULT_HOST, httpHost);

            HttpGet securedResource = new HttpGet("/secured/index.jsp");            
            HttpResponse httpResponse = client.execute(securedResource);
            HttpEntity responseEntity = httpResponse.getEntity();
            String strResponse = EntityUtils.toString(responseEntity);
            int statusCode = httpResponse.getStatusLine().getStatusCode();
            EntityUtils.consume(responseEntity);

            System.out.println("Http status code for Unauthenticated Request: " + statusCode);// Statue code should be 200
            System.out.println("Response for Unauthenticated Request: \n" + strResponse); // Should be login page
            System.out.println("================================================================\n");

            HttpPost authpost = new HttpPost("/j_security_check");
            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
            nameValuePairs.add(new BasicNameValuePair("j_username", "yourusername"));
            nameValuePairs.add(new BasicNameValuePair("j_password", "yourpassword"));
            authpost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

            httpResponse = client.execute(authpost);
            responseEntity = httpResponse.getEntity();
            strResponse = EntityUtils.toString(responseEntity);
            statusCode = httpResponse.getStatusLine().getStatusCode();
            EntityUtils.consume(responseEntity);

            System.out.println("Http status code for Authenticattion Request: " + statusCode);// Status code should be 302
            System.out.println("Response for Authenticattion Request: \n" + strResponse); // Should be blank string
            System.out.println("================================================================\n");

            httpResponse = client.execute(securedResource);
            responseEntity = httpResponse.getEntity();
            strResponse = EntityUtils.toString(responseEntity);
            statusCode = httpResponse.getStatusLine().getStatusCode();
            EntityUtils.consume(responseEntity);

            System.out.println("Http status code for Authenticated Request: " + statusCode);// Status code should be 200
            System.out.println("Response for Authenticated Request: \n" + strResponse);// Should be actual page
            System.out.println("================================================================\n");
        }
        catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}

次の質問があります (参照する行番号は、上記のリンクのコンテキストにあります。StackOverflow では行番号を含めることが許可されていないためです)。

  • 「/j_security_check」(41 行目) とは正確には何ですか? また、作成者は、保護されたリソースの名前の代わりに「j_security_check」を使用する必要があることをどのようにして知ったのでしょうか?

  • 文字列 "strResponse = EntityUtils.toString(responseEntity);" はどうしてですか? (49 行目)、「httpResponse = client.execute(authpost);」の 2 行後です。(47 行目)、文字列 "strResponse = EntityUtils.toString(responseEntity);" とは異なります。(行 59)、「httpResponse = client.execute(securedResource);」の 2 行後です。(57行目)?
    基本的に、47 行目と 57 行目の間で "client" にどのような変更が加えられるのでしょうか?

ありがとうございました

4

2 に答える 2

7

これ/j_security_checkはフォーム アクションであるため、コンテナはこのリクエストが認証用であることを認識し、コンテナがそれを処理します。/j_security_checkEnterprise Java アプリケーション サーバーに固有の認証フォームを送信するための Web ページ アドレスです。

j_usernameおよびj_passwordは、ユーザー名とパスワードの両方を送信するための要求パラメーターの名前です。これら 3 つは、コンテナーがこの要求を認証要求として処理し、送信された要求から必要な情報 (つまり、ユーザー名とパスワード) を取得できるような方法で名前を付ける必要があります (つまりj_security_checkj_usernameと)。j_password

/j_security_check作成者は、J2EE アプリ サーバーに対して認証していると想定しているため、使用する必要があることを知っていました。これは大した仮定ではありません。ポートが 8080 に設定されていることに注意してください。これは、Tomcat などの Java サーバーが通常使用するポートであるため、HTTP サーバーのポート 80 と競合しません。

strResponse47 行目にはログイン要求自体の内容 (何もありません) がstrResponse含まれており、57 行目には保護されたページの内容が含まれています。これは内訳です:

これを Web ブラウザで実行すると、次のようになります。

  • 保護されたページのアドレスを入力して、Enter キーを押します。
  • 認証されていないため、サーバーはログイン フォーム ページで応答します。
  • ユーザー名とパスワードを入力し、[送信] をクリックします。
  • 安全なページが表示されます。サーバーは、最初に要求したアドレスを含む 302 リダイレクト コードと、ブラウザーが保存する認証 Cookie を返します。ブラウザはこのページに再度アクセスしますが、今度はブラウザも Cookie を送信するため、ログイン フォームが表示される代わりに、アクセスしようとしていたページが表示されます。

行 31 は、認証なしの最初のページ アクセスです。行 38 ~ 39 はログイン フォームを表示しています。行 41 ~ 45 は、ユーザー名とパスワードをフォームに入力するのと同じです。
47 行目は送信ボタンを押すようなものです。
49 行目は、サーバーが応答として送信した内容を示しています。行 54 のコメントが「空白文字列にする必要があります」であることに注意してください。ユーザー名とパスワードを送信すると、応答で最も懸念されるのは HTTP ステータスです。ステータス コードを出力する行のコメントには、「ステータス コードは 302 にする必要があります」と書かれています。302 は、ブラウザーにリダイレクトするように指示する HTTP ステータスです。応答ヘッダーには、ブラウザーがリダイレクトするアドレスが含まれます。応答ヘッダーには、認証 Cookie も含まれています。それも印刷されていればいいのですが、これがどのように機能するかを理解するのに役立ちます. コードは 57 行目で手動でリダイレクトを行っていますが、HTTP 応答ヘッダーからアドレスを取得するのではなく、31 行目でアクセスしようとした保護されたページにリダイレクトされることを想定しています。

への最大の変更点は、ブラウザ操作と同様に、client57 行目までに認証 Cookie があることです。clientDefaultHttpClient は、内部ですべてを処理します。

認証 Cookie は、Set-Cookie HTTP ヘッダーの形式でサーバーから取得されます。clientこれにより、Cookie を保存するように指示されます。次に、リクエストを行うときに、クライアントは Cookie データと一緒に Cookie HTTP ヘッダーを送信します。

client最初に、ログイン フォームを含む応答で Cookie を受信し、保存します。がclient記入済みのフォームを送り返すと、その Cookie もリクエストに含まれ、その後のサーバーへのすべてのリクエストにも含まれます。したがって、認証が完了すると、サーバーはその情報を保存し、Cookie に関連付けます。その後、 から後続の要求が来るclientと、サーバーは Cookie を見て、ユーザーが認証済みであることを記憶します。はclient、ブラウザがサーバーとの Cookie データ転送を管理するのと同じことをすべて行います。

于 2014-07-03T12:51:35.913 に答える
0
于 2014-06-27T15:45:42.633 に答える