2016-04-09 5 views
1

AspectJを使用してHttpServletRequest本体を印刷できる単純なログツールを構築しようとしています。私はそれように、私自身の要求ラッパーをコピーリクエストのボディとのHttpServletRequestを交換するなどのjavax Filter.doFilter、HttpServletのdoPostメソッド、doGetメソッド、サービスのすべての実行をキャッチし、簡単なポイントカットSpringセキュリティでMultiReadHttpServletRequestを使用しているときにログインできませんUsernameAndPasswordAuthFilter

を作成した。このため

私はそれを記録することができるように、複数回呼び出すことができます。 - https://github.com/Alotor/test-binding/blob/master/src/java/grails/util/http/MultiReadHttpServletRequest.javaを参照してください。

Springセキュリティフィルタを使用するアプリケーションでボディをログに記録しようとするまではこれまでうまくいきました。今私はログインできません、何とかHttpServletRequestWrapperの実装がSpringにとって重要だと思われますが、どこで、なぜ、私は理解できません。

私のコード(ビットがオリジナルから変更され、それがアイデアを与える):

aspect MyAspect { 
    pointcut httpCalls(HttpServletRequest req, HttpServletResponse resp): 
     args(req, resp, ..) && (execution(void    javax.servlet.Servlet+.service(..)) 
       || execution(void javax.servlet.Servlet+.doGet(..)) 
       ... 
       || execution(void javax.servlet.Filter.doFilter(..)); 

    Object around(HttpServletRequest req, HttpServletResponse resp):httpCalls(req,resp) { 
    ... 
    if (!ThreadContext.getContext().wasReplaced()) { // we need to replace the request 
     reqWrapper = new MultiReadHttpServletRequest(req); 
     ThreadContext.getContext().setWasReplaced(true);   
     obj = proceed(reqWrapper, resp); 
     TraceContextFactory.getFactory().getContext().setWasReplaced(false); 
    } else { 
     obj = proceed(req, resp); 
    } 
    return obj; 
    } 

} 

私は、ログインすることができないと、これは春のセキュリティで動作するように失敗した理由を任意のアイデア? 私は彼らが独自のラッパーを使用しているのを見ましたが、APIは同じであるため、機能するはずです。

私はtomcatでアプリケーションを実行していますが、org.apache.catalinaをインストルメントしていません(これはおそらくアスペクトがtomcatソースコードを製織するのを妨げるクラスの読み込み順序のために機能しません) 。

編集:

私は今の問題はUsernamePasswordAuthenticationFilter.java内にある参照してください。

protected String obtainUsername(HttpServletRequest request) { 
    return request.getParameter(usernameParameter); 
} 

私は私のラッパーを使用した場合にはnull上記戻り、そうでない場合は、「ゲスト」を返す、その私が使用したユーザー名です。私はinputstreamとreaderをオーバーライドしましたが、実際のgetParameter(...)の呼び出しは、org.apache.catalina.connector.RequestFacadeからの元の入力ストリームを使用する基本的な要求によって行われます。

http://localhost:8081/someApp/j_spring_security_check

おかげで、

+0

アスペクトの完全なコードを投稿してください。この短いバージョンでは、 'firstTimeTracking'条件が' true'の場合にのみ 'proceed(...)'を呼び出すようです。 –

+0

@NándorElődFekete - コードを更新しました。どんな助けもありがとう。このコードは、HttpServletRequestWrapperの型(?)に何らかの形で依存する春のセキュリティ以外のすべてのケースで機能します。 – Lin

答えて

1

春のセキュリティパラメータを読み取るために、Tomcatのorg.apache.coyote.Requestと呼ばれるので、私は、ログインができませんでした。要求はInputStreamを使用せず、BufferInputを使用します。いずれにせよ、私はラップされたInputStreamを使用しません。

2つの解決策があります。

  • request.getParametersMap() - (例えばバネセキュリティj_spring_security_checkのログイン、など)ポストコールの場合は、あなたがrequest.getParametersMapを(使用できる)とを生成するためには、それから身体を要求する。
  • javaリフレクションを使用して、org.apach.coyote.RequestのinputBufferを、ストリームから複数回読み取ることができる独自の実装に置き換えます。

最初のオプションは後者が危険すぎるIMHOであるため、私は最初のオプションを選択しました。

関連する問題