Spring BootでSpring Security機能を使う ー データベースを使った認証

spring
この記事は約10分で読めます。

前回、Spring BootでSpring Security機能を有効化する方法について見てきました。

Spring BootでSpring Security機能を使う ー 基礎
引き続きSpring Bootに関する投稿です。今回は、Spring Bootで認証機能(Spring Security)を使用する方法についてのメモです。 環境 Spring Boot 2.0.4.RELEASE Spring Bootで...

次は、Spring BootでSpring Securityの認証機能の1つであるデータベースを使った認証の仕組みについて見ていきます。

Spring Securityの認証処理の仕組み

Webアプリケーションのセキュリティ機能を提供してくれているspring-security-webでは、サーブレットフィルタの仕組みを利用し、認証機能が実現されていることを見てきました。では、実際にフィルタからどのように認証処理が行われているのでしょうか?

仕組みを俯瞰するため、まずは以下に主要なクラスの関連図(概要のため省略あり)をまとめてみます。

概要をまとめると、以下のようになっているようです。

  • 認証処理は、AuthenticationManagerが受け付ける。AuthenticationManagerはインターフェースであり、実装クラスとしてProviderManagerがある。
  • ProviderManagerは、複数の認証プロバイダAuthenticationProvider(実際に認証処理を担当する)を管理しており、認証の問い合わせを受けると、各認証プロバイダに認証処理を委譲する。
  • 認証に成功すると、Authenticationオブジェクトが返される。Authenticationはインターフェースであり、実装クラスはxxAuthenticationTokenのように命名されている。例えば、フォーム認証ではUsernamePasswordAuthenticationTokenが使われている。

と、このように認証マネージャ(実装クラスProviderManager)が複数の認証プロバイダ(具体的な認証処理を行なうクラス達)に認証処理を委譲するように抽象化されていることが分かります。そして、spring-securityに限らずですが、この抽象化がユーザ独自機能を含めたカスタマイズを可能にしています。

Spring Bootでデータベース認証を実装してみる

Spring Bootの大きな特徴は、様々な設定を自動化しすぐに所望する機能を使用することができるような仕組みの提供(autoconfiguration)でした。Spring Bootはデータベース機能(spring-jdbc)を使用するためのコンフィグレーションを提供してくれているため、それを利用することでデータベース認証機能を用意に実装することができます。

ここでは、spring-jdbcを使って組み込みデータベースでの簡単なユーザ管理機能を実装してみたいと思います。

依存関係の定義

今回のサンプルでは、組み込みデータベースのH2を使うこととします。また、データアクセス機能には、spring-jdbcを使います。

UserDetailsの実装

まずは、ユーザ情報を提供する機能について見ていきます。

インターフェースは以下のようになっていますが、今回は既にSpringにある実装のorg.springframework.security.core.userdetails.Userクラスで代用することとします。従って、ここでは簡単のためUserDetailsの実装クラスは作成しません。

インターフェースを見ればメソッド名からどういう実装をすべきか判断することができると思います。ユーザ名、パスワード、ロール、アカウント有効無効、ロック状態や有効期限などの情報を返すクラスを実装すれば良いことが分かります。

参考 

UserServiceDetailsの実装

ユーザ情報に関する操作機能を提供します。メイン機能のインターフェースは以下のようになっており、ユーザ名を引数で受け取り、ユーザ情報を返す仕様となっています。

今回の例では、UserDetails同様にSpringにあるデフォルト実装を利用することとします。今回はデータベース認証機能の実装が目的なので、最初のクラス図で挙げたorg.springframework.security.provisioning.JdbcUserDetailsManagerを使うことにします。このクラスは、JdbcTemplateを使ったデータアクセス機能を提供する抽象クラスJdbcDaoSupportを継承していています(具体的にはJdbcDaoSupportの具象クラスであるJdbcDaoImplを継承)。また、ユーザに関する基本的なCRUD機能の仕様であるUserDetailsManagerインターフェースを実装しています。従って、JdbcUserDetailsManagerクラスを使うことで、ユーザに関する基本的なCRUD機能を享受することができます。

参考 

データベースコンフィグレーション

上記までで、ユーザ情報やユーザ情報操作の基本的な操作を準備することができました。と言っても、デフォルト実装を使用するという方針を定めただけでプログラムは書いていません。

続いて、spring-jdbc機能の設定が必要になりますが、コンフィグレーションはSpring BootのAutoConfigurationが行なってくれます。DataSourceなどのBean定義は基本的には不要で、使用するデータベースの依存関係の追加やapplication.propertiesに必要な設定を記述するだけで、spring-jdbcが提供してくれる機能をインジェクションして使用できるようになっています。

application.properites

データベースに関連する設定は、最後のセクションです。起動時にスキーマ作成と初期データの投入を行うための設定及び、H2 Consoleを使うための設定をしています。

データベースコンフィグレーション

以下の2つを定義します。

上記例では、UserDetailsServiceとしてJdbcUserDetailsManagerを定義しています。また、PasswordEncoderも同様に使いたいのでここで定義していますが、PasswordEncoderFactories.createDelegatingPasswordEncoder()で直接PasswordEncoderの実装クラスを指定していません。プリフィックス型({xxx})がある場合、別のサポートする実装クラスに照合処理を委譲できるようにしています。例えば、{noop}xxxxでは、NoOpPasswordEncoderが使われます(ただし、NoOpPasswordEncoderは@Deprecatedです、実際のサービスでは別のセキュアな実装を使います)。

なお、spring-boot-starter-jdbcでは、デフォルトでHikariDataSourceが使われます。

スキーマとデータ

起動時に定義する内容です。JdbcUserDetailsManagerクラスが想定しているクエリに合わせて、以下のように定義しています。(アカウントのロックや期限などの情報は省略しています)

セキュリティコンフィグレーション

続いて、セキュリティ機能の設定を確認しておきます。今回は、簡易なユーザ管理機能を作るという目的のため、/userというパスに認証・認可を要求するように設定します。

フォーム

ユーザ名とパスワードと受け取るだけの単純なクラスとします。

リポジトリクラス

データアクセスのためのクラスを作成します。ここでは、UserRepositoryとします。リポジトリパターンではインターフェースを定義するかと思いますが、今回は簡単のためインターフェース定義は省略します。

以下サンプルでは、CRUD機能はUserDetailsMangerに委譲するようにしています。

コントローラとビュー

最後に、コントローラとビューを作成します。

ログインフォームは、Spring Securityのデフォルトの機能を使用しています。

動作画面

以下のURLにアクセスすると、ログインフォームへリダイレクトされます。

   http://localhost:8080/user/

このサンプルプログラムでは、admin/adminでログインできます。ログインすると以下のような簡素な画面が表示されます。

H2 Console画面も以下のように表示できます。

まとめ

  • Spring Bootでは、AutoConfiguration機能のおかけで、application.propertiesで最低限の設定をするだけで、spring-jdbcの基本的なコンフィグレーションが行われ、簡単にデータアクセス機能を利用したspring-securityのデータベース認証処理を行なうことができます。
  • spring-boot-starter-jdbcでは、デフォルトのデータソースとしてHikariDataSourceが使われます。
  • UserDetailsServiceの実装クラスであるJdbcUserDetailsManagerを使えば、ユーザに関する基本的なCRUD操作が行えます。
  • PasswordEncoderは、デフォルトでBCryptPasswordEncoderが使われます。

今回使用したサンプルプログラムは以下です。

https://github.com/moritoru81/spring-boot-misc/tree/master/spring-security-database-authentication

参考リンク

 

 

Spring徹底入門 Spring FrameworkによるJavaアプリケーション開発
株式会社NTTデータ
翔泳社
売り上げランキング: 37,650

 

Spring Boot 2 プログラミング入門
掌田津耶乃
秀和システム
売り上げランキング: 7,583

コメント

タイトルとURLをコピーしました