Spring Boot Security Starterのデフォルトにできるだけ近づけながら、Angular&SpringアプリケーションにTOTPソフトトークンを使用した多要素認証を追加したいと思います。
トークンの検証はローカルで行われ(aerogear-otp-javaライブラリを使用)、サードパーティのAPIプロバイダーは使用されません。
ユーザーのトークンの設定は機能しますが、Spring Security Authentication Manager / Providersを利用してトークンを検証することはできません。
TL; DR
- 追加のAuthenticationProviderをSpring Boot Security Starter構成済みシステムに統合する公式の方法は何ですか?
- リプレイ攻撃を防ぐために推奨される方法は何ですか?
ロングバージョン
APIにはエンドポイント/auth/token
があり、そこからフロントエンドはユーザー名とパスワードを提供することでJWTトークンを取得できます。応答には認証ステータスも含まれ、AUTHENTICATEDまたはPRE_AUTHENTICATED_MFA_REQUIREDのいずれかになります。
ユーザーがMFAを必要とする場合、トークンは、許可された単一の権限PRE_AUTHENTICATED_MFA_REQUIRED
と5分の有効期限で発行されます。これにより、ユーザーはエンドポイントにアクセスして/auth/mfa-token
、AuthenticatorアプリからTOTPコードを提供し、完全に認証されたトークンを取得してサイトにアクセスできます。
プロバイダーとトークン
私はMfaAuthenticationProvider
実装する私のカスタムを作成しましたAuthenticationProvider
:
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
// validate the OTP code
}
@Override
public boolean supports(Class<?> authentication) {
return OneTimePasswordAuthenticationToken.class.isAssignableFrom(authentication);
}
そして、(署名されたJWTから取得した)ユーザー名とOTPコードを保持するようOneTimePasswordAuthenticationToken
に拡張AbstractAuthenticationToken
されたです。
構成
私は私のカスタム持ってWebSecurityConfigurerAdapter
、私は私のカスタムを追加し、AuthenticationProvider
経由しますhttp.authenticationProvider()
。JavaDocによると、これは正しい場所のようです:
使用する追加のAuthenticationProviderを追加できます
私の関連部分はSecurityConfig
このように見えます。
@Configuration
@EnableWebSecurity
@EnableJpaAuditing(auditorAwareRef = "appSecurityAuditorAware")
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final TokenProvider tokenProvider;
public SecurityConfig(TokenProvider tokenProvider) {
this.tokenProvider = tokenProvider;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authenticationProvider(new MfaAuthenticationProvider());
http.authorizeRequests()
// Public endpoints, HTML, Assets, Error Pages and Login
.antMatchers("/", "favicon.ico", "/asset/**", "/pages/**", "/api/auth/token").permitAll()
// MFA auth endpoint
.antMatchers("/api/auth/mfa-token").hasAuthority(ROLE_PRE_AUTH_MFA_REQUIRED)
// much more config
コントローラ
AuthController
たAuthenticationManagerBuilder
注射し、すべて一緒にそれを引っ張っています。
@RestController
@RequestMapping(AUTH)
public class AuthController {
private final TokenProvider tokenProvider;
private final AuthenticationManagerBuilder authenticationManagerBuilder;
public AuthController(TokenProvider tokenProvider, AuthenticationManagerBuilder authenticationManagerBuilder) {
this.tokenProvider = tokenProvider;
this.authenticationManagerBuilder = authenticationManagerBuilder;
}
@PostMapping("/mfa-token")
public ResponseEntity<Token> mfaToken(@Valid @RequestBody OneTimePassword oneTimePassword) {
var username = SecurityUtils.getCurrentUserLogin().orElse("");
var authenticationToken = new OneTimePasswordAuthenticationToken(username, oneTimePassword.getCode());
var authentication = authenticationManagerBuilder.getObject().authenticate(authenticationToken);
// rest of class
ただし、投稿に対して/auth/mfa-token
このエラーが発生します。
"error": "Forbidden",
"message": "Access Denied",
"trace": "org.springframework.security.authentication.ProviderNotFoundException: No AuthenticationProvider found for de.....OneTimePasswordAuthenticationToken
Spring Securityが認証プロバイダーを取得しないのはなぜですか?コントローラをデバッグするDaoAuthenticationProvider
と、で唯一の認証プロバイダーであることがわかりますAuthenticationProviderManager
。
私MfaAuthenticationProvider
をBeanとして公開すると、登録されているのは唯一のプロバイダーなので、反対になります。
No AuthenticationProvider found for org.springframework.security.authentication.UsernamePasswordAuthenticationToken.
それで、どうすれば両方を入手できますか?
私の質問
追加を統合するお勧めの方法は何であるAuthenticationProvider
に春ブーツセキュリティスターター構成されたシステムは、私は両方を取得していること、DaoAuthenticationProvider
そして私自身のカスタムMfaAuthenticationProvider
?Spring Boot Scurity Starterのデフォルトを維持し、さらに独自のプロバイダーを追加したいと考えています。
リプレイ攻撃の防止
OTPアルゴリズム自体は、コードが有効なタイムスライス内のリプレイアタックから保護されないことを知っています。RFC 6238はこれを明確にしています
検証者は、最初のOTPに対して検証が正常に発行された後、OTPの2回目の試行を受け入れてはいけません。
保護を実装するための推奨される方法があるかどうか疑問に思っていました。OTPトークンは時間ベースなので、最後に成功したログインをユーザーのモデルに保存し、30秒のタイムスライスごとに1回だけ成功したログインがあることを確認します。もちろん、これはユーザーモデルの同期を意味します。より良いアプローチはありますか?
ありがとうございました。
-
PS:これはセキュリティに関する質問なので、信頼できる情報源や公式な情報源からの回答を探しています。ありがとうございました。