01-spring5
- com.example.securityパッケージ
- com.example.persistenceパッケージ
- src/main/webappフォルダ
- src/main/resources/templatesフォルダ
Spring Securityはサーブレットフィルターベースで動作します。 Spring Securityの十数個のフィルターを、すべて管理しているフィルターが springSecurityFilterChain です。 これは既にweb.xmlのコメント内に記述済みなので、コメントを外してください。
SecurityConfigは、Spring Securityに関する設定を記述するJava Configクラスです。
Java Configであることを示し、かつSpring Securityを有効化するために@EnableWebSecurity
アノテーションを付加してください。
@EnableWebSecurity
アノテーションには@Configuration
が含まれているため、@Configuration
は付加しなくてOKです
後ほど、com.example.security.details
にクラスを作成します。このパッケージをコンポーネントスキャンするためのアノテーションを下記のように付加してください。
@ComponentScan(basePackages = "com.example.security.details")
WebSecurityConfigurerAdapter
クラスを継承してください。
CSSなどの静的コンテンツは、Spring Securityの保護対象から外します。下記のメソッドを追加してください。
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().mvcMatchers("/css/**");
}
configure(HttpSecurity)
をオーバーライドすると、認証認可設定を記述することができます。
下記のメソッドを追加してください。
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin()
.loginPage("/login")
.permitAll();
http.authorizeRequests()
.mvcMatchers("/insert*").hasRole("ADMIN")
.anyRequest().authenticated();
http.logout()
.invalidateHttpSession(true)
.permitAll();
}
ユーザーのパスワードは、平文のままではなくハッシュ化してからDBに保存します。
ユーザーがログインする際は、入力された平文のパスワードをハッシュ化してから、DBに保存されたパスワード(ハッシュ化済み)と比較することで検証します。
PasswordEncoder
をBean定義すればそれが使われます。passwordEncoder()
メソッドに、Beanであることを示すアノテーションを付加してください。
メソッド内でBCryptPasswordEncoder
をnewしてreturnしてください。
AccountRepositoryインタフェースは、DBのユーザー情報を取得します。 内容を確認してください(変更不要)。
AccountRepositoryImplクラスは、AccountRepository
実装クラスです。
@Repository
を付加して、Beanであることを示してください。
このクラスは、既にJdbcConfigクラスでコンポーネントスキャン対象に指定済みです。
findByEmail()
メソッドでユーザー情報の検索を行っています。NamedParameterJdbcTemplate
とResultSetExtractor
を利用しています。
内容を確認してください(変更不要)。
AccountDetailsクラスが、UserDetails
インタフェースを実装していることを確認してください(変更不要)。
このUserDetails
実装クラスが、Spring Securityが利用するログインユーザー情報になります。
getAccount()
メソッドが、account
フィールドを返していることを確認してください(変更不要)。
このメソッドは、後ほど画面にログイン中のユーザー名を表示する際に使われます。
getUsername()
メソッドが、account
のemail
を返すようにしてください。これが、ログイン時に入力するユーザー名を表します。
getPassword()
メソッドが、account
のpassword
を返すようにしてください。これが、ハッシュ化されたパスワードを表します。
getAuthorities()
メソッドが、authorities
フィールドを返すようにしてください。これが、ユーザーが持つロールを表します。
AccountDetailsServiceクラスは、AccountDetails
を返すloadUserByUsername()
メソッドを持っています。
このクラスに@Service
を付加して、ビジネスロジックのBeanであることを示してください。
UserDetailsService
インタフェースを実装していることを確認してください(変更不要)。
loadUserByUsername()
メソッド内で、AccountDetails
をnewしてreturnしてください(コンストラクタにAccountを渡してください)。
MvcInitializerクラスのgetServletConfigClasses()
メソッドが返している配列に、SecurityConfig.class
を追加してください。
追加後のメソッドは下記のようになります。
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{DataSourceConfig.class, JdbcConfig.class, ServiceConfig.class,
MvcConfig.class, SecurityConfig.class};
}
AccountDetailsServiceTestクラスを実行してください。 テストがグリーンになれば成功です。レッドになった場合、AccountDetailsクラスやAccountDetailsServiceクラスの実装を見直してください。
SecurityConfigTestクラスを実行してください。 テストがグリーンになれば成功です。レッドになった場合、SecurityConfigクラスの実装を見直してください。
MvcInitializerTestクラスを少し変更します。 テスト実行前に
getServletConfigClassesTest_withSpringSecurity()
メソッドをテスト対象にするために、@Disabledを削除してくださいgetServletConfigClassesTest()
メソッドをテスト対象から外すために、@Disabledを付加してください
上記の変更後、このクラスを実行してください。 テストメソッドが1つだけ実行されませんが、それ以外のテストメソッドがグリーンになれば成功です。 レッドになった場合、MvcInitializerクラスの実装を見直してください。
演習3で実行したのは
getServletConfigClassesTest()
メソッドです。このメソッドはSecurityConfig.class
が無い状態のテストなので、今回は実行対象から外しています。 それに対して、今回実行しているgetServletConfigClassesTest_withSpringSecurity()
メソッドは、SecurityConfig.class
が有る状態でテストしています。
login.htmlはログイン画面です。内容を確認してください(変更不要)。
この画面に対応するコントローラーはLoginControllerクラスです。
index.htmlに、ログイン中のユーザー名を表示させます。 下記の記述を追加してください。
<p>ようこそ、<span sec:authentication="principal.account.name">John</span>さん!</p>
sec:authorize
属性を利用して、ADMIN
ロールのみ追加画面へのリンクを表示させます。
下記のsec:authorize
属性を追記してください。
<a href="insertMain.html" th:href="@{insertMain}" sec:authorize="hasRole('ADMIN')">新規追加へ</a>
Mainクラスから実行します。 このmain()メソッドを実行後、ブラウザで http://localhost:8080/sample にアクセスして以下の点を確認してください。
- ログイン画面にリダイレクトされる
- 未ログイン時でもCSSが適用されている
- [email protected]/userでログインできる
- 「ようこそ、userさん!」と表示される
- [新規追加へ]のリンクが表示されない
- ブラウザのURLバーに http://localhost:8080/sample/insertMain と入力するとエラー画面に遷移する
- [email protected]/adminでログインできる
- 「ようこそ、adminさん!」と表示される
- [新規追加へ]のリンクが表示される
- 顧客の新規追加ができる
- [ログアウト]ボタンをクリックすると、ログアウト後にログイン画面にリダイレクトされる
- 上記以外のメールアドレス/パスワードを入力すると、ログイン画面にリダイレクトされる
これで演習4は完成です。 次の演習は03-boot2/todo-5.mdに書かれています。