2012-01-05 7 views
3

これは簡単な質問ではありません。私は、ログインとセキュリティでEJB 3.0サービスを保護するためのアーキテクチャーを再考しているからです。rmi ejbコールの再利用可能なログインセッションのコンセプト

私たちは、JBoss 5.1上にEJB3.0アプリケーションを用意しています。このアプリケーションは、SWTクライアントにさまざまなサービスを提供し、データの読み書きを行います。サービスを使用するには、クライアントは、有効なユーザーとパスワードを使用してログインする必要があります。有効なユーザーとパスワードは、LDAPサーバーでSpringSecurityによって参照されます。 SpringSecurityはセッションIDを生成します。セッションIDは、それ以降のサービス呼び出しで再利用されるようにクライアントに返されます。

client       server 
    |        | 
    |-> login(user/password)-------->| 
    |        | 
    | <------- sessionId ------------| 
    |        | 
    |-->serviceXy(sessionId,param1)->| 

状況は明らかです。各サービスメソッドの最初のパラメータである独自のコンテキストオブジェクトにsessionIdを格納します。各サービスメソッドには、指定されたコンテキストオブジェクトからsessionIdを読み込み、セッションがまだ有効かどうかを調べるインターセプタがあります。クライアントはsessionIdでいっぱいになったコンテキストオブジェクトを取得するためにログインサービスを最初に呼び出す必要があり、以後のサービス呼び出しでこのコンテキストオブジェクトを再利用する必要があります。

public class OurContext { 
    private String sessionId; 
} 


@Stateless 
@Interceptors(SecurityInterceptor.class) 
public OurServiceImpl implements OurService { 

    public void doSomething(OurContext context, String param1) { 
     [...] 
    } 
} 

このソリューションで私が気に入らないのは、コンテキストパラメータを使用して各サービスメソッドを分類することです。 rmi呼び出しでhttpセッションのような同様のメカニズムはありませんか?私はコンテキストオブジェクトを、ログイン直後のクライアント(?)で作成されたある種類のセッションに入れ、SecurityInterceptorがこの "魔法のコンテキスト"からsessionIdを読むことができるように各サービス呼び出し時にサーバーに渡すことを考えています"

このような何か:

OurContext ctx = service.login("user","password"); 
Magical(Jboss)Session.put("securContext", ctx); 
service.doSomething("just the string param"); 

答えて

2

すでにアプリケーションサーバーを使用しているので、あなたが一般的にJAASを通じて提供内蔵のEJBのセキュリティメカニズムを使用してしなければならないようです。 4.xのjboss行で、jboss用に独自のJAASプラグインを実装した場合、リモートリクエストで渡される(特別な意味を持つ)コンテキストマップ(jbossリモート呼び出しフレームワーク)。私はしばらくのうちにjbossを使用していないので、これが5.1製品にどのようにマップされているのかよく分かりませんが、同様の機能を持っていると想像しなければなりません。これはもちろん、あなたが何かjboss特有のものを実装しようとしていることを前提としています。

+0

あなたの答えについて多くのことを考えた後、私はより良い解決策を見つけることができないと認めなければなりません。だから、私たちは政治的理由でコンテキスト・シナリオを維持します、hrmpf – martin

1

EJBにはいくつかの種類のセッションメカニズムがありますが、リモート呼び出しが開始されるとすべて開始し、終了すると終了します。古いものはトランザクションのコンテキストです(Adam Bienはこれまでにこれについて書いていました)。そして、新しいものはCDIセッションスコープです。

一般的な考え方とは異なり、このスコープはhttpセッションスコープを反映するだけでなく、リモートセッションのようにhttpセッションが存在しない場合、単一のコールチェーンまたはメッセージ配信(mdbs)を表します。

このようなセッションでは、リモートSWTクライアントはセッションIDをリモートサービスに渡す必要がありますが、そこから呼び出されるローカルBeanはこの「cdi」セッションから取得できます。

もう1つのオプションは、jtahlbornと同じです。独自のログインモジュールを使用すると、デフォルトのものではなくカスタムプリンシパルを返すことができます。あなたのコードは、最初に通常のプリンシパルを要求し、それをキャストしようとすることができます。

この問題はコンテナ固有であり、JBossは常にそれを忘れています。それは、すべての更新後にかなり壊れて、ユーザーは次のバージョンでそれを修正するために蹴って叫ばなければなりません(それ以降のバージョンで再び壊れるのを見るためだけです)。 JBossが本当にこれをサポートしていなければ、それは無限の戦いです。

さらに別のオプションは、ユーザーがsessionIdを名前として使用してログインさせることです。その背後にあるログインモジュールは、すべてを受け入れ、sessionIdを「名前」として持つセキュリティコンテキスト内にプリンシパルを置く単純なモジュールです。これはちょっと変わったことですが、文字列で表現できるデータをセキュリティコンテキストに取り込むために、これをうまく使用しています。もちろん、ここではクライアントに通常のコンテナ認証をさせる必要があります。これは、最初はSpringセキュリティを使用しています。

0

私たちは移植性があり、特定のアプリケーションサーバーに依存しない別のアプローチに行きました。さらに、私たちのセキュリティ実装は、EJBアプローチの制限から解放されます(これは20年前に閉鎖されたと考えられていましたが、再び登場しました)。

トップを見下ろす:

同じデータで作業するためのメソッドを持つクラスを提供するサーバがあります。 クライアントはデータを提供し、特定のメソッドを呼び出します。

私たちのアプローチは、すべてのデータ(したがって、クライアントとサーバーの間の通信)を「ビジネスオブジェクト」にすることです。すべてのBOはスーパークラスを拡張します。このスーパークラスにはセッションIDが含まれています。 loginメソッドは、そのidを提供して返します。すべてのクライアントは、1つのBOで受信したIDをサーバーに送信する次のIDにコピーするだけです。リモート(またはローカル)に呼び出すことができるすべてのメソッドは、最初に受信したIDを持つセッションオブジェクトを取得します。セッションオブジェクトを返すメソッドは、セキュリティ制約(EKBアプローチのような権限ではなく、ロールに基づく)もチェックします。

+1

かなりうまく聞こえます。どのようなパラメタを持たないサービスメソッドのためのアプローチは? – martin

関連する問題