Spring Securityのプログラムによる使用
-
06-07-2019 - |
質問
プレゼンテーション層のWicket Authプロジェクトで Wicket を使用しているため、Springと統合しました。セキュリティ。これは、認証のために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。参照ドキュメントのセッション固定攻撃保護には次のように記載されています。
セッション固定攻撃は、可能な限り潜在的なリスクです 悪意のある攻撃者が作成する サイトへのアクセスによるセッション 別のユーザーにログインするよう説得する 同じセッション(それらを送信することにより セッション識別子を含むリンク たとえば、パラメータとして)。春 セキュリティはこれに対して保護します 新しいものを作成して自動的に ユーザーがログインするときのセッション。 この保護を必要としない、または 他の要件と競合する を使用して動作を制御できます セッション固定保護 上の属性、3 オプション:
- migrateSession-新しいセッションを作成し、既存のセッションをコピーします 新しいセッションのセッション属性。これがデフォルトです。
- none-何もしません。元のセッションは保持されます。
- newSession-新しい「クリーン」を作成します;セッション、コピーせずに 既存のセッションデータ。
認証は機能しますが、Spring Securityにはかなり慣れていないので、答えが必要な質問がいくつかあります:
- 通常、ログインの場合、認証情報を
j_spring_security_check
にPOSTし、Spring Securityに実際の認証コードを実行させます。セッション固定攻撃から保護したいのですが、プログラムによるログインを実行するときに取得できますか?そうでない場合、それを取得するには何をしなければなりませんか? - プログラムによるログアウトを実行するにはどうすればよいですか
- プログラムによるログインとログアウトを使用する場合、SpringがそれらのURLをインターセプトしないようにするにはどうすればよいですか
更新:
セッション固定攻撃保護のために、署名 startNewSessionIfRequired(HttpServletRequest request、boolean migrateAttributes、SessionRegistry sessionRegistry)
を使用してSessionUtilsクラスのメソッドを呼び出す必要があるようです。
渡す必要がある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)プログラムによるログアウト
- HttpServletRequest.getSession(false).invalidateを呼び出す
- SecurityContextHolder.clearContext()を呼び出す
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.");
}