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の構成は以下の通りです.
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"/>