1

私が取り組んでいるこのアプリケーションで「メソッド レベル」のセキュリティを試しています。アイデアは、DWR を使用してプレゼンテーション層から呼び出されるメソッドを保護することです。今、私は自分のメソッドに次の注釈を追加しようとしました:

@PreAuthorize("isAuthenticated() and hasRole('ROLE_CUSTOMER')")

そして、私のセキュリティコンテキストの対応するエントリ:

<global-method-security pre-post-annotations="enabled" />

同様の行で、@Secured アノテーションを試しました。

@Secured({"ROLE_CUSTOMER" })

そして、私のセキュリティコンテキストの対応するエントリ:

<global-method-security secured-annotations="enabled" />

理想的には、ユーザーが認証されていない場合は、「サインイン」ページにリダイレクトされ、「ROLES」がチェックされないようにする必要があります。この場合、認証されていないユーザーであっても、このメソッドを呼び出すと「AccessDeniedException」が発生します。このようなシナリオでは、ユーザーをログイン ページにリダイレクトする必要があります。

それを進めるために、カスタム AccessDenied Handler を作成して、accessdenied 例外を処理しようとさえしました。残念ながら、ハンドラーは呼び出されませんでしたが、例外がスローされました。

構成は次のとおりです。

<access-denied-handler ref="customAccessDeniedHandler"/>

これには、同じファイルで定義された対応するハンドラー Bean があります。

まだ運がありません。accessdeniedhandler が呼び出されることはありません。

要件を要約すると、メソッドを確保する必要があります。このメソッドが呼び出され、ユーザーが認証されていない場合、ユーザーは「サインイン」ページにリダイレクトされます (現在、アクセス拒否の実行がスローされています)。

あなたの助けに感謝します..

編集 1 : セキュリティ コンテキストからのスニペットを次に示します。

<http>
    <intercept-url pattern="/*sign-in.do*" requires-channel="$secure.channel}" />
    .....
    ..... 
    .....
    <intercept-url pattern="/j_acegi_security_check.do" requires-channel="${secure.channel}" />

    <intercept-url pattern="/*.do" requires-channel="http"  />
    <intercept-url pattern="/*.do\?*" requires-channel="http" />
    <form-login login-page="/sign-in.do" authentication-failure-url="/sign-in.do?login_failed=1"
        authentication-success-handler-ref="authenticationSuccessHandler" login-processing-url="/j_acegi_security_check.do"/>

    <logout logout-url="/sign-out.do" logout-success-url="/index.do" />

    <session-management session-authentication-strategy-ref="sessionAuthenticationStrategy" />
        <access-denied-handler ref="customAccessDeniedHandler"/>
  </http>
    <beans:bean id="customAccessDeniedHandler" class="com.mypackage.interceptor.AccessDeniedHandlerApp"/>
4

3 に答える 3

0

私は DWR にあまり詳しくありませんが、これが RPC メカニズムであることは知っています。問題は、クライアント側の JavaScript によって送信される RPC リクエストが、ブラウザをナビゲートするユーザーによって開始される通常のページ リクエストではないことです。このような RPC 要求への応答は、ブラウザーではなく JavaScript コードによって処理されるため、ブラウザーを現在のページから移動させることはできません。

あなたができることは次のとおりです。

  1. 熱心な認証の一種を実装します。ユーザーを単純な .jsp ログイン ページにリダイレクトしてから、DWR (または任意の種類の RPC) 要求を行う webapp (URL) にアクセスできるようにします。
  2. リモート プロシージャによってスローされたものが何らかの形でクライアント側に伝播された場合はAccessDeniedException、ログイン ダイアログをポップアップし、AJAX 要求でユーザーの資格情報を送信するなどして、javascript コードから処理を試みることができます。(この場合、返されたセッション ID を必ず保存し、後続の各リクエストで返送してください。)
于 2013-05-07T12:34:42.023 に答える
0

Okay, I have not had much success finding why I got an AccessDeniedException. Regardless, I've worked my way out of it till the time I find the reason. Here's a couple of approaches I took:

1) As mentioned by Zagyi, I was able to propagate the AccessDenied Exception over to the client side. I could create an exception handler to and redirect the user to the sign in page.

However, I took a different approach (which may not be the most optimal but seems to work as of now. Here's what I've done:

1) Created a DWRAjaxFilter and mapped to only the Remote Objects I am interested in. This would bean only the DWR calls to these remote methods get intercepted by the filter. This is because I do not want all DWR exposed methods to as for a sign in.

   <create creator="spring" javascript="downloadLinksAjaxService">
       <param name="beanName" value="downloadLinksAjaxService" />
       <include method="methodOne" />
       <include method="methodTwo" />  
       <filter class="com.xyz.abc.interceptor.DwrAjaxFilter"></filter>
   </create>

2) Here is the actual filter implementation:

public class DwrSessionFilter implements AjaxFilter {
    public Object doFilter(final Object obj, final Method method,
            final Object[] params, final AjaxFilterChain chain)
            throws Exception {

        SecurityContext context = SecurityContextHolder.getContext();
        Authentication auth = context.getAuthentication();
        if (!auth.isAuthenticated()
                || auth.getAuthorities().contains(
                        new GrantedAuthorityImpl("ROLE_ANONYMOUS"))) {
            throw new LoginRequiredException("Login Required");
        } else {
            return chain.doFilter(obj, method, params);
        }
    }
}

3) Here is the client side handler:

function errorHandler(message, exception){

                if(exception && exception.javaClassName == "org.directwebremoting.extend.LoginRequiredException") {

                  document.location.reload();
                }
            }

4) I also added and exception mapper for DWR so that I could convert JAVA exceptions to JS exceptions:

<convert match="java.lang.Exception" converter="exception">
            <param name='include' value='message'/>
        </convert> 

5) This seems to work well as of now. I'm still testing this to see if this fails somewhere.

Would appreciate any more inputs.

于 2013-05-10T03:56:10.703 に答える