独自のBFDを作成するのはそれほど難しくありません。Spring Security 3.0と同様に、アプリケーションリスナーを追加するだけです(正しい方向に向けてくれたStephen Cに感謝します)。
このリスナーは、認証の失敗が発生したときに呼び出されます。
@Component
public class AuthenticationFailureListener
implements ApplicationListener<AuthenticationFailureBadCredentialsEvent> {
@Autowired
private UserDao userDao;
public void onApplicationEvent(AuthenticationFailureBadCredentialsEvent ev) {
String username = ev.getAuthentication().getName();
User user = userDao.find("name", username);
if (user != null) { // only for existing users
user.reportLoginFailure();
userDao.commit();
}
}
}
認証に失敗するたびに、ユーザーに通知されます。たとえば、ユーザーは認証失敗カウンターをインクリメントし、特定のしきい値に達すると自分で非アクティブ化します。
ユーザーが正しく認証されると、以下のリスナーがユーザーに通知します(たとえば、認証失敗カウンターをリセットできるユーザー)。
@Component
public class AuthenticationSuccessEventListener
implements ApplicationListener<AuthenticationSuccessEvent>{
@Autowired
private UserDao userDao;
public void onApplicationEvent(AuthenticationSuccessEvent event) {
String username = event.getAuthentication().getName();
User user = userDao.find("name", username);
user.reportLoginOK();
userDao.commit();
}
}
上記のリスナーは追加のXML構成を必要とせず、Springによって自動的に取得されます(Springコンポーネントスキャンパッケージに含まれている場合)。
トランザクションの構成によっては、このソリューションで失敗したログインカウントがほぼ同時に発生した場合、それらを見逃す可能性があります。これは、ユーザーをロードしてから変更を保存する代わりに、単一のUPDATEクエリでカウンターを更新する場合に防ぐことができます。
上記のリスナーを拡張して、他のBDFパターン、たとえば、多数の(ランダムな)ユーザー名をスキャンしている単一のIPを検出することもできます。