14

Web サービスを介してログインを実行する必要がある Java Web アプリケーションを作成しています。もちろん、私が使用しているアプリケーション サーバー (glassfish v2) で提供されているレルムはどれもうまくいきません。したがって、私は自分で書かなければなりませんでした。しかし、私が書いたレルムの実装は完全に Glassfish に結び付けられており、他のアプリケーション サーバーでそのまま使用することはできないようです。

カスタム Realm を実装するための標準的または広くサポートされている方法はありますか? そのレルムを .war から展開することは何らかの方法で可能ですか?それとも、常にサーバー自身のクラスパスからロードする必要がありますか?

4

5 に答える 5

10

注:以下の回答はJava EE 5にのみ有効です。他の回答の1つで私の注意を引いたように、JavaEE6はこれをサポートしています。したがって、Java EE 6を使用している場合は、この回答を読むのではなく、他の関連する回答を読んでください。

私自身の調査とこの質問への回答から、私が見つけた答えは次のとおりです。JAASは標準インターフェースですが、JAAS Realm + LoginModuleをさまざまなアプリケーションサーバーに記述、デプロイ、統合するための統一された方法はありません。

Glassfish v2では、LoginModuleまたはRealm自体を実装する独自の内部クラスのいくつかを拡張する必要があります。ただし、LoginModuleインターフェースの多くのメソッドがGlassfishのスーパークラスでfinalとマークされているため、ログインプロセス全体をカスタマイズすることはできません。カスタムLoginModuleクラスとRealmクラスは(アプリケーションではなく)ASクラスパスに配置する必要があり、レルムは手動で登録する必要があります(.warからの展開はできません)。

Tomcatの状況は少し良くなっているようです。これにより、独自のRealmとLoginModuleを完全にコーディングし、独自のJAASRealm(実際の作業をRealmとLoginModuleの実装に委任する)を使用してアプリケーションサーバーに構成できます。 。ただし、Tomcatでさえ、.warからカスタムレルムをデプロイすることはできません。

私の結果を示したアプリケーションサーバーのどれも、すべてのJAASコールバックを十分に活用できないようであることに注意してください。それらはすべて、基本的なユーザー名とパスワードのスキームのみをサポートしているようです。それよりも複雑なものが必要な場合は、JavaEEコンテナで管理されていないソリューションを見つける必要があります。

参考までに、そして私の質問へのコメントで求められたので、ここに私がGlassfishV2用に書いたコードがあります。

まず、レルムの実装は次のとおりです。

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;
}
}

最後に、レルムではLoginModuleに関連付ける必要があります。これは、JAAS構成ファイルレベルで実行されます。これは、glassfishv2ではyourDomain/ config/login.confにあります。そのファイルの最後に次の行を追加します。

myWebserviceRealm { // use whatever String is returned from you realm's getJAASContext() method
    my.auth.login.WebserviceLoginModule required;
};

これが、Glassfishでうまく機能するようになった理由です。繰り返しになりますが、このソリューションはアプリケーションサーバー間で移植可能ではありませんが、私が知る限り、既存の移植可能なソリューションはありません。

于 2009-04-06T23:30:20.333 に答える
7

カスタム Realm を実装するための標準的または広くサポートされている方法はありますか? そのレルムを .war から展開することは何らかの方法で可能ですか?それとも、常にサーバー自身のクラスパスからロードする必要がありますか?

カスタム Realm を実装する標準的な方法、またはより一般的な用語でカスタム認証モジュールを実装する標準的な方法は絶対にあります。これは、JASPIC/JASPI/JSR 196 SPI/APIを介して実行できます。JASPIC は、完全な Java EE 6 実装の標準部分ですが、残念ながら Java EE 6 Web プロファイルの一部ではありません。

ただし、JASPIC は Java EE 6 の一部であるにもかかわらず、ベンダーによって最適にサポートされていません。GlassFish と WebLogic は非常に優れた実装をしているようですが、JBoss AS と Geronimo はもう少し問題があります。このトピックに関する JBoss の主任エンジニア (Anil Saldhana) は、現時点ではデフォルトで JASPIC をアクティブにすることを拒否しているとさえ述べています。Jboss AS 7.1 の最も重大なバグのいくつかは最近修正されましたが、JBoss 7.1.x の公開リリースは予定されておらず、JBoss AS 7.2 はまだしばらく先であるため、現時点では少なくとも JBoss JASPIC は面倒。

もう 1 つの残念な問題は、実際の認証モジュールは標準化されている可能性がありますが、それを構成するための宣言的な方法 (XML ファイルを読み取る) が標準化されていないことです。

そのレルムを .war から展開することは何らかの方法で可能ですか?それとも、常にサーバー自身のクラスパスからロードする必要がありますか?

JASPIC では、認証モジュール (「レルム」) を実際に .war からロードできます。これが仕様で保証されているかどうかは 100% わかりませんが、テストした 4 つのサーバー (GlassFish、WebLogic、Geronimo、および JBoss AS) はすべてこれをサポートしていました。残念ながら、Geronimo のプログラムによる登録にはある種の競合状態が存在するため、ホット デプロイを 2 回実行するという厄介な回避策が必要ですが、最終的には .war からモジュールをロードする必要があります。

独自のメカニズムとして、少なくとも JBoss AS は、.war または .ear からのモジュール (例: org.jboss.security.auth.spi.AbstractServerLoginModule のサブクラス) のロードを常にサポートしてきました。

最近、このトピックに関するブログ記事を書きました。これには詳細が含まれています。

于 2012-12-13T13:33:22.480 に答える
2

レルムはアプリケーション アーティファクトではなく、コンテナ アーティファクトであるため、WAR からレルムを展開することはできません (したがって、「コンテナ ベースのセキュリティ」というフレーズ)。コンテナーによって提供される特定のレルムを使用するようにアプリを構成できますが、アプリケーション自体はこれを提供できません。

つまり、コンテナはすべて異なり、これらのレルムは移植可能ではありませんが、移植性を求めている場合は、単純な常識で、コンテナと統合するために必要なわずかなグルー コードに違いを減らすことができます。

于 2009-04-07T00:02:28.210 に答える
1

Suns のドキュメントをざっと見てみると、アプリ サーバー固有のクラスを拡張するカスタム LoginModule を作成する必要があるようです。これは私には少し逆向きで、Glassfish の制限のようです。

これをより移植可能にしたい場合は、実装の大部分を標準 JavaEE インターフェースに対して開発されたカスタム LoginModule に配置し、Glassfish 固有の薄い実装層を用意して、標準の移植可能な実装に委譲することをお勧めします。 .

于 2009-04-06T22:32:17.257 に答える
-2

このテーマに関するSunの記事をチェックしてください。

私は実際にこれを自分で行ったことはありませんが、各ASには、新しいレルム(セキュリティドメイン)を登録するオプションがあると確信しています。

おそらく100%移植可能ではなく、ASごとに異なる構成XMLが必要になる場合がありますが、基本的に、コードが異なる理由はありません。

于 2009-04-06T07:05:29.903 に答える