注:以下の回答は、Java EE 5にのみ有効です。その他の回答の1つに注目したように、Java EE 6はこれをサポートしています。したがって、Java EE 6を使用している場合は、この回答を読まずに、他の関連する回答をお読みください。
JAASは標準インターフェースですが、JAAS Realm + LoginModuleをさまざまなアプリケーションサーバーに記述、配置、統合する統一された方法はありません。
Glassfish v2では、LoginModuleまたはRealm自体を実装する独自の内部クラスの一部を拡張する必要があります。ただし、LoginModuleインターフェイスの多くのメソッドがGlassfishのスーパークラスでfinalとマークされているため、ログインプロセス全体をカスタマイズすることはできません。カスタムLoginModuleクラスとRealmクラスはASクラスパスに配置する必要があり(アプリケーションのものではない)、レルムを手動で登録する必要があります(可能であれば.warからのデプロイメントなし)。
Tomcatでは、独自のRealmとLoginModuleを完全にコーディングできるようになり、独自のJAASRealmを使用してアプリケーションサーバーに構成できるようになります(実際の作業を実装に委譲します)。レルムとLoginModule)。しかし、Tomcatでも、.warからカスタムレルムを展開することはできません。
結果が表示されたアプリケーションサーバーは、すべてのJAASコールバックを最大限に活用できないようです。それらのすべては、基本的なユーザ名+パスワード方式だけをサポートしているようです。それより複雑なものが必要な場合は、Java EEコンテナによって管理されていないソリューションを見つける必要があります。
参考のために、私の質問にコメントで尋ねられたので、ここにGlassFish V2のために書いたコードがあります。
まず第一に、ここでのレルムの実装です:
public class WebserviceRealm extends AppservRealm {
private static final Logger log = Logger.getLogger(WebserviceRealm.class.getName());
private String jaasCtxName;
private String hostName;
private int port;
private String uri;
@Override
protected void init(Properties props) throws BadRealmException, NoSuchRealmException {
_logger.info("My Webservice Realm : init()");
// read the configuration properties from the user-supplied properties,
// use reasonable default values if not present
this.jaasCtxName = props.getProperty("jaas-context", "myWebserviceRealm");
this.hostName = props.getProperty("hostName", "localhost");
this.uri = props.getProperty("uri", "/myws/EPS");
this.port = 8181;
String configPort = props.getProperty("port");
if(configPort != null){
try{
this.port = Integer.parseInt(configPort);
}catch(NumberFormatException nfe){
log.warning("Illegal port number: " + configPort + ", using default port (8181) instead");
}
}
}
@Override
public String getJAASContext() {
return jaasCtxName;
}
public Enumeration getGroupNames(String string) throws InvalidOperationException, NoSuchUserException {
List groupNames = new LinkedList();
return (Enumeration) groupNames;
}
public String getAuthType() {
return "My Webservice Realm";
}
public String getHostName() {
return hostName;
}
public int getPort() {
return port;
}
public String getUri() {
return uri;
}
}
そしてLoginModule実装:
public class WebserviceLoginModule extends AppservPasswordLoginModule {
// all variables starting with _ are supplied by the superclass, and must be filled
// in appropriately
@Override
protected void authenticateUser() throws LoginException {
if (_username == null || _password == null) {
throw new LoginException("username and password cannot be null");
}
String[] groups = this.getWebserviceClient().login(_username, _password);
// must be called as last operation of the login method
this.commitUserAuthentication(groups);
}
@Override
public boolean commit() throws LoginException {
if (!_succeeded) {
return false;
}
// fetch some more information through the webservice...
return super.commit();
}
private WebserviceClient getWebserviceClient(){
return theWebserviceClient;
}
}
は最終的に、レルムにログインモジュールに接続する必要があります。これはJAAS設定ファイルレベルで行われます。このレベルは、glassfish v2ではyourDomain/config/login.confにあります。そのファイルの末尾に次の行を追加します。
myWebserviceRealm { // use whatever String is returned from you realm's getJAASContext() method
my.auth.login.WebserviceLoginModule required;
};
これは、グラスフィッシュで私のために働いているものです。ここでも、このソリューションはアプリケーションサーバー間で移植できませんが、私が知る限り、既存のポータブルソリューションはありません。
あなたのレルムコードの例を投稿できますか? –