私はプレゼンテーション層のWicket Authプロジェクトで Wicket を使用しているため、Spring Securityと統合しました。これは私のためにWicketが認証のために呼び出すメソッドです:
_@Override
public boolean authenticate(String username, String password) {
try {
Authentication request = new UsernamePasswordAuthenticationToken(
username, password);
Authentication result = authenticationManager.authenticate(request);
SecurityContextHolder.getContext().setAuthentication(result);
} catch (AuthenticationException e) {
return false;
}
return true;
}
_
私のSpring Security XML構成の内容(内)は次のとおりです。
_<http path-type="regex">
<form-login login-page="/signin"/>
<logout logout-url="/logout" />
</http>
<global-method-security secured-annotations="enabled" />
<authentication-manager alias="authenticationManager"/>
<authentication-provider user-service-ref="userService">
<password-encoder ref="bcryptpasswordencoder" />
</authentication-provider>
_
リファレンスドキュメントのセクション 2.3.6。Session Fixation Attack Protection は次のように述べています。
セッション固定攻撃は、悪意のある攻撃者がサイトにアクセスしてセッションを作成し、別のユーザーに同じセッションでログインするように誘導する可能性のある潜在的なリスクです(パラメーターとしてセッション識別子を含むリンクを送信することにより、例)。 Spring Securityは、ユーザーがログインしたときに新しいセッションを作成することにより、これを自動的に保護します。この保護が必要ない場合、または他の要件と競合する場合は、のsession-fixation-protection属性を使用して動作を制御できます。 3つのオプションがあります。
- migrateSession-新しいセッションを作成し、既存のセッション属性を新しいセッションにコピーします。これがデフォルトです。
- なし-何もしません。元のセッションは保持されます。
- newSession-既存のセッションデータをコピーせずに、新しい「クリーン」セッションを作成します。
認証は機能しますが、私はSpring Securityにかなり慣れていないので、いくつかの質問があり、答えも必要です
j_spring_security_check
_にして、Spring Securityに実際の認証コードを実行させます。セッション固定攻撃から保護したいのですが、取得しますか?プログラマティックログインを実行するときと、そうでない場合、それを取得するにはどうすればよいですか?更新:セッション固定攻撃から保護するために、SessionUtilsクラスのメソッドをstartNewSessionIfRequired(HttpServletRequest request, boolean migrateAttributes, SessionRegistry sessionRegistry)
で呼び出す必要があるようです。
渡す必要があるSessionRegistryインスタンスを取得するにはどうすればよいですか?エイリアスIDを作成する方法や、IDまたは名前を取得する方法が見つかりません。
多分それはあなたの質問への完全な答えではありませんが、多分それはあなたを助けるかもしれません。
プログラムによるログインを使用しないときに呼び出されるコードですが、標準のコードは次の場所にあります。
org.springframework.security.ui.webapp.AuthenticationProcessingFilter
あなたはあなたのコードでこれに触発されたと思います。よく似ています。
同様に、標準的な方法で/j_spring_security_logout
にアクセスしたときに実行されるコードは、次の場所にあります。
org.springframework.security.ui.logout.LogoutFilter
LogoutFilterは複数のハンドラーを呼び出します。使用しているハンドラーはorg.springframework.security.ui.logout.SecurityContextLogoutHandler
と呼ばれるため、同じコードをアプローチで呼び出す場合があります。
あなたは確かにセッション固定攻撃を受け入れるでしょう。これを修正するために、Springのコードから再び「インスピレーション」を受けることができます。新しいセッションを作成するには、明らかにhttpsessionにアクセスする必要があるため、リファクタリングを行う必要がある場合があります。
メソッド SessionUtils
.startNewSessionIfRequired
が表示された場合。
これにより、認証が新しいセッションに移行されます。このメソッドを直接呼び出すことも、コードを少しだけリファクタリングすることもできます。
プログラムによるログアウトについては、ユーザーをログアウトする必要があるときにsession.invalidate()
を呼び出すだけで、それほど問題はありません。これは、一般的なセキュリティの観点から必要なすべてを実行しますが、セッションでいくつかのことをクリーンアップする必要があるかもしれないことを覚えておいてください。フィルターなどの非常に複雑なセットがあり、ユーザーが残りのリクエストでログアウトしていることを確認する必要がある場合は、次のように追加できます。
SecurityContextHolder.getContext().setAuthentication(null);
URLのインターセプトについては、それらを未使用のものに設定して無視することができます!設定でインターセプトをオフにできるかどうかはわかりません。本当に削除したい場合は、AuthenticationProcessingFilter
を確認してください。これをカスタマイズできます。これを行う場合は、提供されている名前空間を使用せずに、Spring Security xmlを手動でセットアップする必要があります。それほど難しくはありませんが、古いドキュメントを見ると、その方法がわかります。
お役に立てれば!
1)プログラムによるログアウト
2)特定のURLをインターセプトしないようにSpring Securityに指示します。これは、アプリケーションのURLスペースの設定方法によって異なります。すべてのページ(/ logInと/ logoutを除く)がコンテキスト/ myAppにある場合、次のようにできます。
<http ....>
<intercept-url pattern="/myApp/**" ..>
....
</http>
プログラムによるログインで問題が発生しました。すべてのauthenticationManager.authenticate(...)
およびSecurityContextHolder.getContext().setAuthentication(...)
メソッドを呼び出しましたが、セッションに問題がありました。セッションを適切に管理するには、次の行を追加する必要がありました。
HttpSession session = request.getSession();
session.setAttribute("SPRING_SECURITY_CONTEXT", SecurityContextHolder.getContext());
これは、上記のサンプルコードからは明らかではありませんでした。詳しくは http://forum.springsource.org/showthread.php?t=69761
プログラムによるログアウトを行うには、org.springframework.security.core.AuthenticationException
をスローすることもできます。たとえば、SessionAuthenticationException
です。この場合、ExceptionTranslationFilter
はログアウトを開始します。
あなたはこれを試すことができます
try {
HttpSession session = request.getSession(false);
if (session != null) {
session.invalidate();
}
SecurityContextHolder.clearContext();
} catch (Exception e) {
logger.log(LogLevel.INFO, "Problem logging out.");
}