1. 序章
Spring Securityは、Springベースのアプリケーションを保護するための標準です。 ログインやログアウトなど、ユーザーの認証を管理するためのいくつかの機能があります。
このチュートリアルでは、焦点を当てます SpringSecurityを使用した手動ログアウト。
読者はすでに標準を理解していると想定します 春のセキュリティログアウトプロセス。
2. 基本的なログアウト
いつ ユーザーがログアウトを試みると、現在のセッション状態にいくつかの影響があります。 2つのステップでセッションを破棄する必要があります。
- HTTPセッション情報を無効にします。
- 認証情報が含まれているため、SecurityContextをクリアします。
これらの2つのアクションは、 SecurityContextLogoutHandler。
それを実際に見てみましょう:
@Configuration
public class DefaultLogoutConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.logout(logout -> logout
.logoutUrl("/basic/basiclogout")
.addLogoutHandler(new SecurityContextLogoutHandler())
);
}
}
SecurityContextLogoutHandlerはデフォルトでSpringSecurityによって追加されることに注意してください。ここでは、わかりやすくするためにこれを示しています。
3. クッキークリアログアウト
多くの場合、ログアウトでは、ユーザーのCookieの一部またはすべてをクリアする必要があります。
これを行うには、すべてのCookieをループし、ログアウト時に期限切れにする独自のLogoutHandlerを作成できます。
@Configuration
public class AllCookieClearingLogoutConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.logout(logout -> logout
.logoutUrl("/cookies/cookielogout")
.addLogoutHandler((request, response, auth) -> {
for (Cookie cookie : request.getCookies()) {
String cookieName = cookie.getName();
Cookie cookieToDelete = new Cookie(cookieName, null);
cookieToDelete.setMaxAge(0);
response.addCookie(cookieToDelete);
}
})
);
}
}
実際、SpringSecurityはCookieClearingLogoutHandler を提供しています。これは、Cookieを削除するためのすぐに使用できるログアウトハンドラーです。
4. Clear-Site-Dataヘッダーログアウト
同様に、特別なHTTP応答ヘッダーを使用して同じことを実現できます。 ここで、Clear-Site-Dataヘッダーが機能します。
基本的に、 Clear-Data-Site ヘッダーは、要求元のWebサイトに関連付けられている閲覧データ(Cookie、ストレージ、キャッシュ)をクリアします。
@Configuration
public class ClearSiteDataHeaderLogoutConfiguration extends WebSecurityConfigurerAdapter {
private static final ClearSiteDataHeaderWriter.Directive[] SOURCE =
{CACHE, COOKIES, STORAGE, EXECUTION_CONTEXTS};
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.logout(logout -> logout
.logoutUrl("/csd/csdlogout")
.addLogoutHandler(new HeaderWriterLogoutHandler(new ClearSiteDataHeaderWriter(SOURCE)))
);
}
}
ただし、ストレージクレンジングでは、1種類のストレージのみをクリアすると、アプリケーションの状態が破損する可能性があります。 したがって、不完全なクリアにより、ヘッダーは要求が安全である場合にのみ適用されます。
5. リクエストに応じてログアウト
同様に、 HttpServletRequest.logout()メソッドを使用してユーザーをログアウトできます。
まず、リクエストに応じて logout()を手動で呼び出すために必要な構成を追加しましょう。
@Configuration
public static class LogoutOnRequestConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/request/**")
.authorizeRequests(authz -> authz.anyRequest()
.permitAll())
.logout(logout -> logout.logoutUrl("/request/logout")
.addLogoutHandler((request, response, auth) -> {
try {
request.logout();
} catch (ServletException e) {
logger.error(e.getMessage());
}
}));
}
}
最後に、すべてが期待どおりに機能することを確認するためのテストケースを作成しましょう。
@Test
public void givenLoggedUserWhenUserLogoutOnRequestThenSessionCleared() throws Exception {
this.mockMvc.perform(post("/request/logout").secure(true)
.with(csrf()))
.andExpect(status().is3xxRedirection())
.andExpect(unauthenticated())
.andReturn();
}
6. 結論
要約すると、Spring Securityには、認証シナリオを処理するための多くの組み込み機能があります。 これらの機能をプログラムで使用する方法を習得すると、常に便利です。
いつものように、これらの例のコードはGitHubでから入手できます。