春のセキュリティは私を覚えています
1. 概要
このチュートリアルでは、SpringSecurityを使用してWebアプリケーションでRememberMe機能を有効にして構成する方法を示します。 セキュリティと簡単なフォームログインを備えたMVCアプリケーションのセットアップについてはすでに説明しました。
このメカニズムは、複数のセッションにわたってユーザーを識別できるようになります。したがって、最初に理解する必要があるのは、RememberMeはセッションがタイムアウトした後にのみ開始されるということです。 デフォルトでは、これは30分間非アクティブになった後に発生しますが、タイムアウトはweb.xmlで構成できます。
注:このチュートリアルは、標準のCookieベースのアプローチに焦点を当てています。 永続的なアプローチについては、 Spring Security – Persistent RememberMeガイドをご覧ください。
2. セキュリティ構成
Javaを使用してセキュリティ構成を設定する方法を見てみましょう。
@Configuration
@EnableWebSecurity
public class SecSecurityConfig extends WebSecurityConfigurerAdapter {
@Bean("authenticationManager")
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user1").password("{noop}user1Pass").roles("USER")
.and()
.withUser("admin1").password("{noop}admin1Pass").roles("ADMIN");
}
@Override
protected void configure(final HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/anonymous*").anonymous()
.antMatchers("/login*").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login.html")
.loginProcessingUrl("/login")
.failureUrl("/login.html?error=true")
.and()
.logout().deleteCookies("JSESSIONID")
.and()
.rememberMe().key("uniqueAndSecret")
;
}
}
ご覧のとおり、 RememberMe()メソッドを使用した基本構成は非常に単純ですが、追加のオプションによって非常に柔軟なままです。 ここで重要なのはキーです。これはアプリケーション全体のプライベート値シークレットであり、トークンのコンテンツを生成するときに使用されます。
さらに、トークンが有効な時間は、 tokenValiditySeconds()を使用して、デフォルトの2週間から1日まで構成できます。
rememberMe().key("uniqueAndSecret").tokenValiditySeconds(86400)
同等のXML構成も確認できます。
<http use-expressions="true">
<intercept-url pattern="/anonymous*" access="isAnonymous()" />
<intercept-url pattern="/login*" access="permitAll" />
<intercept-url pattern="/**" access="isAuthenticated()" />
<form-login login-page='/login.html'
authentication-failure-url="/login.html?error=true" />
<logout delete-cookies="JSESSIONID" />
<remember-me key="uniqueAndSecret"/>
</http>
<authentication-manager id="authenticationManager">
<authentication-provider>
<user-service>
<user name="user1" password="{noop}user1Pass" authorities="ROLE_USER" />
<user name="admin1" password="{noop}admin1Pass" authorities="ROLE_ADMIN" />
</user-service>
</authentication-provider>
</authentication-manager>
3. ログインフォーム
ログインフォームは、フォームログインに使用したものと似ています。
<html>
<head></head>
<body>
<h1>Login</h1>
<form name='f' action="login" method='POST'>
<table>
<tr>
<td>User:</td>
<td><input type='text' name='username' value=''></td>
</tr>
<tr>
<td>Password:</td>
<td><input type='password' name='password' /></td>
</tr>
<tr>
<td>Remember Me:</td>
<td><input type="checkbox" name="remember-me" /></td>
</tr>
<tr>
<td><input name="submit" type="submit" value="submit" /></td>
</tr>
</table>
</form>
</body>
</html>
新しく追加されたチェックボックス入力-remember-meへのマッピングに注意してください。 この追加された入力は、remembermeactiveでログインするのに十分です。
このデフォルトパスは、次のように変更することもできます。
.rememberMe().rememberMeParameter("remember-me-new")
4. クッキー
このメカニズムは、ユーザーがログインしたときに追加のCookie(「remember-me」Cookie)を作成します。
Remember Me cookie には、次のデータが含まれています。
- username –ログインしたプリンシパルを識別します
- ExpirationTime –Cookieを期限切れにします。 デフォルトは2週間です
- MD5 hash –前の2つの値– usernameとexpirationTimeに加えて、passwordと事前定義されたkey
ここで最初に気付くのは、ユーザー名とパスワードの両方がCookieの一部であるということです。つまり、どちらかを変更すると、Cookieは無効になります。 また、ユーザー名はCookieから読み取ることができます。
さらに、remember me cookieがキャプチャされた場合、このメカニズムは潜在的に脆弱であることを理解することが重要です。 Cookieは、有効期限が切れるまで、または資格情報が変更されるまで、有効で使用可能です。
5. 実際には
Remember meメカニズムが機能していることを簡単に確認するには、次のことができます。
- 私をアクティブにしてログインしてください
- セッションの有効期限が切れるのを待ちます(またはブラウザで JSESSIONID Cookieを削除します)
- ページを更新
私がアクティブであることを覚えていない場合、Cookieの有効期限が切れた後、ユーザーはログインページにリダイレクトされる必要があります。 私のことを思い出してください。ユーザーは、新しいトークン/ Cookieを使用して、ログインしたままになります。
6. 結論
このチュートリアルでは、セキュリティ構成でRemember Me機能を設定および構成する方法を示し、Cookieに入力されるデータの種類について簡単に説明しました。
実装はサンプルのGithubプロジェクトにあります。これはEclipseベースのプロジェクトであるため、そのままインポートして実行するのは簡単です。
プロジェクトがローカルで実行されている場合、login.htmlはlocalhostでアクセスできます。