3

セキュリティがSpringSecurityによって処理されるSpringMVCアプリケーションがあります。

UIは、RPCアプローチを使用してサーバーからデータを取得するGWTを使用して構築されています。

UIでセッションの有効期限が切れたときの状況を処理する必要があります。たとえば、RPC AsyncCallbackはSessionExpiredExceptionタイプの例外を取得し、「セッションの有効期限が切れています。更新リンクをクリックしてください」などのメッセージをウィンドウにポップアップ表示できます。

誰かがそのような問題に対処しましたか?

ありがとう。

4

2 に答える 2

4

着信GWT呼び出しの処理には、SpringMVCコントローラーまたはサーブレットを使用すると思います。次のロジックを持つことができます

try{
    // decode payload from  GWT call
    com.google.gwt.user.server.rpc.RPC.decodeRequest(...)
    // get spring bean responsible for actual business logic
    Object bean = applicationContext.getBean(beanName);
    // execute business logic and encode response
    return RPC.invokeAndEncodeResponse(bean, ….)
} catch (com.google.gwt.user.server.rpc.UnexpectedException ex) {
    // send unexpected exception to client
    return RPC.encodeResponseForFailure(..., new MyCustomUnexpectedException(), …) ;
}

この場合の解決策

HttpServletRequest request = getRequest() ; 
if (request.getRequestedSessionId() != null && !request.isRequestedSessionIdValid()) {
    return RPC.encodeResponseForFailure(..., new MyCustomSessionExpiredException(), …) ;
} else {
    // first code snippet goes here
}

次に、クライアント側のコードでカスタムセッションの期限切れの例外をキャッチします。RPCを直接使用しない場合は、GWTとSpringの間のブリッジ実装に関する詳細を提供してください。

また、GWTコンパイラにMyCustomSessionExpiredExceptionタイプをシリアル化ホワイトリストに含めるように強制する必要があります(GWTセキュリティポリシーがクライアント側への例外の伝播を停止する場合を防ぐため)。解決策:各同期インターフェイスの各メソッドシグネチャにMyCustomSessionExpiredExceptionタイプを含めます。

@RemoteServiceRelativePath("productRpcService.rpc")
public interface ProductRpcService extends RemoteService {
    List<Product> getAllProducts() throws ApplicationException;
    void removeProduct(Product product) throws ApplicationException;
}

MyCustomSessionExpiredException extends ApplicationException

次に、クライアント側のコードにポップアップを表示します。

public class ApplicationUncaughtExceptionHandler implements GWT.UncaughtExceptionHandler {
    @Override        
    public void onUncaughtException(Throwable caught) {
        if (caught instanceof MyCustomSessionExpiredException) {
            Window.alert("Session expired");
        }
    }
}

// Inside of EntryPoint.onModuleLoad method
GWT.setUncaughtExceptionHandler(new ApplicationUncaughtExceptionHandler());
于 2012-12-12T18:00:52.177 に答える
1

少し調べて、ソリューションをここにアップロードしましたhttp://code.google.com/p/gspring/source/browse/#svn%2Ftrunk%2Fsample%2Fsession-expired%253Fstate%253Dclosed

mvn jetty:run-warチェックアウトした後、デモを表示してに移動するために使用しますrpc-security-sample/index.htm

それを解決するには2つの方法があります

1つ目は、メソッドの呼び出し中RemoteServletにスローするGWTのデリゲートプロキシを渡すことです。これには、すべてのRPCサービスメソッドでSessionExpiredException宣言する必要があります。Exception例:http ://code.google.com/p/gspring/source/browse/#svn%2Ftrunk%2Fsample%2Fsession-expired%253Fstate%253Dclosed

手順:

  1. 最初にインターセプトする新しいフィルターを開発する

  2. 簡単にするためにSessionExpiredException継承できる各RPCメソッドサービスで宣言します(実装者でこれに従う必要はありません)RuntimeException

  3. 親ジェネリックAsyncCallbackハンドラーを開発する

  4. http://code.google.com/p/gspring/ソリューションを使用して、すべての着信RCPリクエストを処理します。

2つ目は、はるかに単純です。401HTTPエラーを返し、UI側で処理します(GWTネイティブの一般的な例外にはHTTPステータス番号が含まれます)。例:http ://code.google.com/p/gspring/source/browse/#svn%2Ftrunk%2Fsample%2Fsession-expired-401

2番目のアプローチは最も単純で、サービスメソッドコントラクトで例外を宣言する必要はありません。ただし、最初のアプローチに従うと、ある程度の柔軟性が得られます。最後のログイン時刻(の)などの追加情報を含めることができます。また、2番目のアプローチでは、ブラックリストに登録されたユーザーのようSessionExpiredExceptionに継承される新しい例外を導入できます(たとえば、ユーザーがSecurityExceptionセッション)または、たとえば、ユーザーがロボットのように同じアクションを頻繁に実行する場合(キャプチャを渡すように求められる場合があります)など。

于 2012-12-16T19:15:48.840 に答える