Spring Security登録が戻る前にアドレスを要求する機能


以下の部分の説明内容はSpring Security 3.1公式文書9.1章の個人翻訳です.
    Spring Securityフィルタチェーンの最後から3番目の層Exception Translation Filterは以下の3つの作業を完了します.
    保護されたリソースユーザが認証されていないか、または認証されていないかをユーザが要求すると、対応するAuthentication ExceptionまたはAccess DeniedExceptionが例外的に投げ出されます.
    1)ユーザがAuthentication Exceptionを認証していないと、内蔵のAuthentication EntryPointに処理を実行し、適切な応答(HTTPエラーコードなど)をユーザに返す.デフォルトのLoginUrlAuthentication EntryPointは、予め設定されたurlにリダイレクトを要求します.
    2)ユーザ認証がAccess DeniedException異常である場合、匿名のユーザであればまだユーザ未認証と見なし、Authentication Entication EntryPoint処理に任せます.さもなければ内蔵のAccess DeniedHandler処理に渡します.デフォルトでは、HTTPステータスコード403を返す応答ですが、対応するurlを設定してリダイレクトしてもいいです.
    3)Authentication EntryPoint処理を起動する前に、Exception Translation Filterは、現在要求されている関連データをSavedRequestオブジェクトとして保存し、ログイン後に取得するために、デフォルトの実装はHttpSession Request CacheとしてHttpSessionに保存します.
    上記の機能は、<security:http aut-config=“true”の時に、SpringコンテキストのBeanとして関連するオブジェクトが自動的に配置されます.
    上記の説明の中で最も重要なのは第三点であり、実際には私達のページ処理クラスはこのRequest Cacheオブジェクトを取得するだけで、ログインプログラムにジャンプする前の要求データを取得することができます.以下の例はSpring MVCに基づくものであるが、Spring SecurityはWeb工学においてFilterとして存在し、どのMVCフレームも原理を知っていれば同じ機能を実現できる.
    Spring Securityの構成は以下の通りです.
<security:http auto-config="true" authentication-manager-ref="authenticationManager">
    <!--      -->
    <security:form-login login-page="/login.html"/>
    <!--      -->
    <!-- ... -->
</security:http>
    私たちはログインページのlogin.およびログインプロセスのlogin.doのプロセッサBeanにRequestCacheを注入すると宣言しています.デフォルトではSpringコンテキストにはRequest Cacheの例が一つしかありません.Spring MVCでない場合は、他のMVCフレームを使用して、SpringアプリケーションのコンテキストからRequestCacheのインスタンスを取得するために自分で工夫する必要があります.
private RequestCache requestCache = null;
 
@Required
@Resource
public void setRequestCache(RequestCache requestCache) {
    this.requestCache = requestCache;
}
    このように、login.doの処理中に、現在要求されているrequestとreponseオブジェクトでRequest Cacheから保存されているSavedRequestの例を取得することができます.Spring MVCではないなら、他のMVCフレームを使うなら、自分で工夫してrequestとreponseオブジェクトを得る必要があります.
SavedRequest savedRequest = requestCache.getRequest(request, response);
//         
String redirectUrl = "/index.html";
//   1         login.html,   ExceptionTranslationFilter       ,SavedRequest   null
//   2   GET          ,      POST ,        ,           
if (savedRequest != null) {
    if("GET".equals(savedRequest.getMethod())) {
        redirectUrl = savedRequest.getRedirectUrl();
    }
    //       requestCache
    //      removeRequest           request response  
    requestCache.removeRequest(request, response);
}
//         ,   Spring MVC   ,   MVC            
return "redirect:" + redirectUrl;
    もちろん、このようにしても足りないです.もし情報をsessionに保存したくないなら、どうすればいいですか?もし私達はユーザが認証していないか、あるいは保護された資源にアクセスしていない場合は、より多くのことをどうすればいいですか?この時、私たちは自分のAuthentication Entication EntryPoint、Access DeniedHandlerとRequest Cacheを実現できます.自分はSpringコンテキストの中で、Spring Securityのメカニズムを使ってデフォルトの存在のExcetionTranslation Filterを交替します.(このような場合Spring文脈には複数のRequest Cacheの例があるかもしれませんので、beanをカスタマイズする際には特別なbeanNameを与え、bean名注入に必要なRequest Cacheを指定します.)
<security:custom-filter ref="myExceptionTranslationFilter" position="EXCEPTION_TRANSLATION_FILTER"/>