SpringSecurityの動作原理とカスタマイズ
最終更新日: 2021年3月9日
R8 | R9
資料
2019年7月4日 Wagby Tech Meet 2019 で発表した資料です。Spring Security の概要およびシングル・サインオンについて説明しています。
PasswordEncoderのカスタマイズ
Spring が提供する PasswordEncoder の仕組みに準拠した、パスワードハッシュ化のカスタマイズ方法を説明します。
1. PasswordEncoder インタフェースの実装クラスを用意する
Spring Security が提供しているorg.springframework.security.crypto.password.PasswordEncoder
インタフェースの実装クラスを用意します。なお Spring Security に同梱されている PasswordEncoder 派生クラスを利用することもできます。その場合は独自クラスの作成は不要です。
2. Configuration クラスを作成する
カスタマイズクラスとして Spring の Configuration クラスを作成し、1. で用意した PasswordEncoder を Bean 定義します。
@Configuration
public class MyConfiguration {
/**
* {@link PasswordEncoder} の bean 定義。
* @return {@link PasswordEncoder}
*/
@Bean
public PasswordEncoder passwordEncoder() {
return new ${任意のPasswordEncoderクラス};
}
}
パッケージ名が「jp.jasminesoft.wagby」の場合は、作成した Configuration クラスは customize/java/jp/jasminesoft/wagby/autoconfiguration フォルダにに配置してください。
3. admin, jobadmin の初期データを用意する
export/data_init/init/juser フォルダを customize/webapp/WEB-INF/export/init/juser へコピーし、item_0.xml, item_1.xml 内の <password> 要素の値を書き換えます。いずれもハッシュ化前のパスワードは "wagby" です。
"wagby" という文字を 2. で定義した PasswordEncoder に対応したハッシュ値に置き換えてください。パスワードのハッシュ値を事前に求める場合は、インターネットで公開されているサービスをご利用いただくことができます。例えば次のようなサービスがあります。[2019年3月現在]
[参考] MyConfiguration クラスのサンプル
customize/java/jp/jasminesoft/wagby/autoconfiguration/MyConfiguration.java ファイルのサンプルを示します。ここでは Spring が提供する BCryptPasswordEncoder を使ってハッシュ値を求めています。
package jp.jasminesoft.wagby.autoconfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
/**
* カスタマイズ用の Configuration クラスです。
* {@link PasswordEncoder} を独自実装に変更しています。
*
* @author JasmineSoft
* @version $Revision$ $Date$
*/
@Configuration
public class MyConfiguration {
/**
* {@link PasswordEncoder} の bean 定義。
* @return {@link PasswordEncoder}
*/
@Bean
public PasswordEncoder passwordEncoder() {
// BCrypt を利用する。
// ストレッチング回数には15を指定。
// ストレッチング回数を省略するとデフォルトの10が適用される。
return new BCryptPasswordEncoder(15);
}
}
OIDC認証におけるユーザ識別子のカスタマイズ
Wagby の OpenID Connect (OIDC) 認証では、emailフィールドをユーザー識別子に用いるように設定変更しています。具体的には application.properties に次の行を出力するようにしています。[詳細...]
spring.security.oauth2.client.provider.google.user-name-attribute=email
このユーザー識別子をカスタマイズするポイントを用意しています。
具体的には、OidcUsernameResolverインタフェースの実装クラスをBeanとして登録します。customize/java/jp/jasminesoft/wagby/autoconfigurationフォルダにSampleUsernameResolver.javaを用意した例を示します。
@Component
public class SampleUsernameResolver implements OidcUsernameResolver {
@Override
public String resolve(Map<String, Object> claims, String username) {
if ("hoge@gmail.com".equals(username)) {
// hoge@gmail.com で認証した場合は、Wagby 側では
// 特別に admin としてログオンさせる。
return "admin";
}
return username;
}
}
- @Componentアノテーションを付与してBean登録するようにしてください。
- 上の例では、"hoge@gmail.com" というアカウントを "admin" に差し替えるものです。
応用例
次のようなケースがあります。
- メールアドレスの “@gmail.com” 部分を削除する。
- resolve()メソッドの第一引数claimsに格納されている他のフィールドを組み合わせてユーザー識別子とする。
- claimsにはOPから取得したユーザーの属性情報が格納されています。格納情報については以下を参照(Googleの場合) https://developers.google.com/identity/protocols/OpenIDConnect#obtainuserinfo