一般に、認証スキームはすべてプロキシとサーバーの両方によって機能します。一部のもの (基本およびダイジェスト) は、プロキシとサーバーで同時に使用できます。プロキシとサーバーの認証を区別する方法については次を参照してください。
getPasswordAuthentication()
メソッドをオーバーライドする必要があります。なお、このメソッドは abstract ではなく、デフォルト実装は処理を行いません。次にもっとも単純な例を示します。
class MyAuthenticator extends Authenticator { public PasswordAuthentication getPasswordAuthentication () { return new PasswordAuthentication ("user", "password".toCharArray()); } }
この例では、各 HTTP 認証の相互作用に使用するユーザー名「user」とパスワードを返します。さらに実践的な例では、java.net.Authenticator の別のメソッドを使用して認証を必要とする HTTP 要求について詳細情報を取得します。資格の要求をそれぞれ処理する方法について決定するには、getPasswordAuthentication() を実装して、次のメソッドのいずれかを呼び出します。
Authenticator.setDefault (authinstance);
ここで authinstance
は、すでに宣言済みの実装クラスのインスタンスです。これが呼び出されない場合、認証は無効になり、サーバー認証エラーが IOException オブジェクト経由でユーザーコードに返されます。HTTP 実装は、インストールされると、可能な場合に、キャッシュされた資格経由またはシステムから取得可能な資格経由で自動認証を試行します。正しい資格が使用できない場合は、ユーザーのオーセンティケータを呼び出して、この資格を取得できます。
特定のスキームを必ず使用する必要がある場合は、次のシステムプロパティーを設定してデフォルト時の動作を修正できます。
-Dhttp.auth.preference="scheme"
コマンド行でこのプロパティーの設定を行う場合は、-D を指定します。「http.auth.preference」はプロパティー名であり、scheme は使用するスキーム名です。提案したスキームのリストにサーバーがこのスキームを含めない場合は、デフォルト設定が有効となります。
getRequestingPrompt() メソッドは、サーバーが提供するような基本認証レルムを返します。
-Dhttp.auth.digest.validateServer="true" -Dhttp.auth.digest.validateProxy="true"
getRequestingPrompt() メソッドは、サーバーが提供するようなダイジェスト認証レルムを返します。
Microsoft Windows プラットフォームでは、NTLM 認証により、ユーザーのオーセンティケータオブジェクトを要求せずにシステムからユーザー資格の取得を試みます。このような資格をサーバーが受け入れない場合は、ユーザーのオーセンティケータが呼び出されます。
NTLM をサポートする以前に Authenticator クラスが定義されているため、NTLM ドメインフィールドの API をさらにサポートすることはできません。ドメインを指定するには、次の 3 つのオプションがあります。
java.security.krb5.conf
を使用して実現できます。たとえば、java -Djava.security.krb5.conf=krb5.conf \ -Djavax.security.auth.useSubjectCredsOnly=false \ ClassName
com.sun.security.jgss.krb5.initiate
という名前の標準エントリを検索します。spnegoLogin.conf
を指定できます。
com.sun.security.jgss.krb5.initiate { com.sun.security.auth.module.Krb5LoginModule required useTicketCache=true; };次のように java を実行します。
java -Djava.security.krb5.conf=krb5.conf \ -Djava.security.auth.login.config=spnegoLogin.conf \ -Djavax.security.auth.useSubjectCredsOnly=false \ ClassName
java.net.Authenticator
を指定して HTTP SPNEGO モジュールにユーザー名とパスワードを指定できます (つまり、資格キャッシュは使用できません)。オーセンティケータでチェックする必要がある認証情報は、getRequestingScheme()
を使用して取得可能なスキームのみです。値は「Negotiate」である必要があります。つまり、オーセンティケータ実装は次のようになります。
class MyAuthenticator extends Authenticator { public PasswordAuthentication getPasswordAuthentication () { if (getRequestingScheme().equalsIgnoreCase("negotiate")) { String krb5user; char[] krb5pass; // get krb5user and krb5pass in your own way .... return (new PasswordAuthentication (krb5user, krb5pass)); } else { .... } } }注意:
java.net.Authenticator
の仕様では、ユーザー名とパスワードを同時に取得するように設計されています。このため、JAAS 構成ファイルに principal=xxx
を指定しないでください。
http.auth.preference
を指定して、サーバーが特定のスキームを要求するかぎりそのスキームが常に使用されるように指定できます。このシステムプロパティーに対して「SPNEGO」または「Kerberos」を使用できます。「SPNEGO」は、GSS/SPNEGO メカニズムを使用してネゴシエーションスキームに応答します。「Kerberos」は、GSS/Kerberos メカニズムを使用してネゴシエーションスキームに応答します。通常、Microsoft 製品に対して認証を行う場合に「SPNEGO」を使用できます。値「Kerberos」も Microsoft サーバーに対して動作します。Kerberos は、ネゴシエーションは認識するが SPNEGO は認識しないサーバーに対してのみ使用する必要があります。http.auth.preference
が設定されていない場合、選択される内部順序は次のようになります。
http.auth.preference
が SPNEGO または Kerberos に設定されている場合、失敗する場合でも単にネゴシエーションスキームを試行することが要求されていると想定されます。
ほかのどのようなスキームにもフォールバックせず、HTTP 応答から 401 または 407 のエラーを受け取ることを表す IOException
がスローされます。保護されているファイルを取得するには、次のファイルを準備する必要があります。
RunHttpSpnego.java
のコードリスト
import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.net.Authenticator; import java.net.PasswordAuthentication; import java.net.URL; public class RunHttpSpnego { static final String kuser = "username"; // your account name static final String kpass = password; // retrieve password for your account static class MyAuthenticator extends Authenticator { public PasswordAuthentication getPasswordAuthentication() { // I haven't checked getRequestingScheme() here, since for NTLM // and Negotiate, the usrname and password are all the same. System.err.println("Feeding username and password for " + getRequestingScheme()); return (new PasswordAuthentication(kuser, kpass.toCharArray())); } } public static void main(String[] args) throws Exception { Authenticator.setDefault(new MyAuthenticator()); URL url = new URL(args[0]); InputStream ins = url.openConnection().getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(ins)); String str; while((str = reader.readLine()) != null) System.out.println(str); } }
krb5.conf
のコードリスト
[libdefaults] default_realm = AD.LOCAL [realms] AD.LOCAL = { kdc = kdc.ad.local }
login.conf
のコードリスト
com.sun.security.jgss.krb5.initiate { com.sun.security.auth.module.Krb5LoginModule required doNotPrompt=false useTicketCache=true; };
次に、RunHttpSpnego.java
をコンパイルして実行します。
java -Djava.security.krb5.conf=krb5.conf \ -Djava.security.auth.login.config=login.conf \ -Djavax.security.auth.useSubjectCredsOnly=false \ RunHttpSpnego \ http://www.ad.local/hello/hello.html
次のように表示されます。
Feeding username and password for Negotiate <h1>Hello, You got me!</h1>
ドメインユーザーとして Windows マシン上で実行しているか、またはすでに kinit
コマンドを発行して資格キャッシュを取得している Linux か Solaris マシン上で実行している場合は、次のようになります。クラス MyAuthenticator
は完全に無視され、出力は次のようになります
<h1>Hello, You got me!</h1>これは、ユーザー名とパスワードが参照されないことを示しています。これはシングルサインオンと呼ばれます。また、次のように実行して、
java RunHttpSpnego \ http://www.ad.local/hello/hello.htmlフォールバックがどのように実行されるかを確認できます。この場合は、次のように表示されます。
Feeding username and password for ntlm <h1>Hello, You got me!</h1>