Skip to content

Latest commit

 

History

History
184 lines (143 loc) · 10.1 KB

todo-4.md

File metadata and controls

184 lines (143 loc) · 10.1 KB

演習4 Spring Securityによる認証・認可

使うプロジェクト

01-spring5

主に使うパッケージ

  • com.example.securityパッケージ
  • com.example.persistenceパッケージ
  • src/main/webappフォルダ
  • src/main/resources/templatesフォルダ

TODO 4-01

Spring Securityはサーブレットフィルターベースで動作します。 Spring Securityの十数個のフィルターを、すべて管理しているフィルターが springSecurityFilterChain です。 これは既にweb.xmlのコメント内に記述済みなので、コメントを外してください。

TODO 4-02

SecurityConfigは、Spring Securityに関する設定を記述するJava Configクラスです。 Java Configであることを示し、かつSpring Securityを有効化するために@EnableWebSecurityアノテーションを付加してください。

@EnableWebSecurityアノテーションには@Configurationが含まれているため、@Configurationは付加しなくてOKです

TODO 4-03

後ほど、com.example.security.detailsにクラスを作成します。このパッケージをコンポーネントスキャンするためのアノテーションを下記のように付加してください。

@ComponentScan(basePackages = "com.example.security.details")

TODO 4-04

WebSecurityConfigurerAdapterクラスを継承してください。

TODO 4-05

CSSなどの静的コンテンツは、Spring Securityの保護対象から外します。下記のメソッドを追加してください。

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().mvcMatchers("/css/**");
    }

TODO 4-06

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();
    }

TODO 4-07

ユーザーのパスワードは、平文のままではなくハッシュ化してからDBに保存します。 ユーザーがログインする際は、入力された平文のパスワードをハッシュ化してから、DBに保存されたパスワード(ハッシュ化済み)と比較することで検証します。 PasswordEncoderをBean定義すればそれが使われます。passwordEncoder()メソッドに、Beanであることを示すアノテーションを付加してください。

TODO 4-08

メソッド内でBCryptPasswordEncoderをnewしてreturnしてください。

TODO 4-09

AccountRepositoryインタフェースは、DBのユーザー情報を取得します。 内容を確認してください(変更不要)。

TODO 4-10

AccountRepositoryImplクラスは、AccountRepository実装クラスです。 @Repositoryを付加して、Beanであることを示してください。 このクラスは、既にJdbcConfigクラスでコンポーネントスキャン対象に指定済みです。

TODO 4-11

findByEmail()メソッドでユーザー情報の検索を行っています。NamedParameterJdbcTemplateResultSetExtractorを利用しています。 内容を確認してください(変更不要)。

TODO 4-12

AccountDetailsクラスが、UserDetailsインタフェースを実装していることを確認してください(変更不要)。 このUserDetails実装クラスが、Spring Securityが利用するログインユーザー情報になります。

TODO 4-13

getAccount()メソッドが、accountフィールドを返していることを確認してください(変更不要)。 このメソッドは、後ほど画面にログイン中のユーザー名を表示する際に使われます。

TODO 4-14

getUsername()メソッドが、accountemailを返すようにしてください。これが、ログイン時に入力するユーザー名を表します。

TODO 4-15

getPassword()メソッドが、accountpasswordを返すようにしてください。これが、ハッシュ化されたパスワードを表します。

TODO 4-16

getAuthorities()メソッドが、authoritiesフィールドを返すようにしてください。これが、ユーザーが持つロールを表します。

TODO 4-17

AccountDetailsServiceクラスは、AccountDetailsを返すloadUserByUsername()メソッドを持っています。 このクラスに@Serviceを付加して、ビジネスロジックのBeanであることを示してください。

TODO 4-18

UserDetailsServiceインタフェースを実装していることを確認してください(変更不要)。

TODO 4-19

loadUserByUsername()メソッド内で、AccountDetailsをnewしてreturnしてください(コンストラクタにAccountを渡してください)。

TODO 4-20

MvcInitializerクラスgetServletConfigClasses()メソッドが返している配列に、SecurityConfig.classを追加してください。 追加後のメソッドは下記のようになります。

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{DataSourceConfig.class, JdbcConfig.class, ServiceConfig.class,
                MvcConfig.class, SecurityConfig.class};
    }

TODO 4-21

AccountDetailsServiceTestクラスを実行してください。 テストがグリーンになれば成功です。レッドになった場合、AccountDetailsクラスAccountDetailsServiceクラスの実装を見直してください。

TODO 4-22

SecurityConfigTestクラスを実行してください。 テストがグリーンになれば成功です。レッドになった場合、SecurityConfigクラスの実装を見直してください。

TODO 4-23

MvcInitializerTestクラスを少し変更します。 テスト実行前に

  • getServletConfigClassesTest_withSpringSecurity()メソッドをテスト対象にするために、@Disabledを削除してください
  • getServletConfigClassesTest()メソッドをテスト対象から外すために、@Disabledを付加してください

上記の変更後、このクラスを実行してください。 テストメソッドが1つだけ実行されませんが、それ以外のテストメソッドがグリーンになれば成功です。 レッドになった場合、MvcInitializerクラスの実装を見直してください。

演習3で実行したのはgetServletConfigClassesTest()メソッドです。このメソッドはSecurityConfig.classが無い状態のテストなので、今回は実行対象から外しています。 それに対して、今回実行しているgetServletConfigClassesTest_withSpringSecurity()メソッドは、SecurityConfig.classが有る状態でテストしています。

TODO 4-24

login.htmlはログイン画面です。内容を確認してください(変更不要)。

この画面に対応するコントローラーはLoginControllerクラスです。

TODO 4-25

index.htmlに、ログイン中のユーザー名を表示させます。 下記の記述を追加してください。

<p>ようこそ、<span sec:authentication="principal.account.name">John</span>さん!</p>

TODO 4-26

sec:authorize属性を利用して、ADMINロールのみ追加画面へのリンクを表示させます。 下記のsec:authorize属性を追記してください。

<a href="insertMain.html" th:href="@{insertMain}" sec:authorize="hasRole('ADMIN')">新規追加へ</a>

TODO 4-27

Mainクラスから実行します。 このmain()メソッドを実行後、ブラウザで http://localhost:8080/sample にアクセスして以下の点を確認してください。

  • ログイン画面にリダイレクトされる
    • 未ログイン時でもCSSが適用されている
  • [email protected]/userでログインできる
    • 「ようこそ、userさん!」と表示される
    • [新規追加へ]のリンクが表示されない
    • ブラウザのURLバーに http://localhost:8080/sample/insertMain と入力するとエラー画面に遷移する
  • [email protected]/adminでログインできる
    • 「ようこそ、adminさん!」と表示される
    • [新規追加へ]のリンクが表示される
    • 顧客の新規追加ができる
  • [ログアウト]ボタンをクリックすると、ログアウト後にログイン画面にリダイレクトされる
  • 上記以外のメールアドレス/パスワードを入力すると、ログイン画面にリダイレクトされる

Well done!

これで演習4は完成です。 次の演習は03-boot2/todo-5.mdに書かれています。