一般に、認証スキームはすべてプロキシとサーバーの両方によって機能します。 一部のもの(基本およびダイジェスト)は、プロキシとサーバーで同時に使用できます。 プロキシとサーバーの認証を区別する方法については次を参照してください。
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サーバーに対して動作します。 これは、ネゴシエーションは認識するが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>