🤖

Spring Security

2023/11/20に公開
  • Main機能
    • 認証
    • 認可
  • 強化機能
    • Session機能
    • CSRF機能
    • ブラウザのセキュリティ対策機能との連携機能

Spring Security Module Structures

Module Name Description
spring-security-core 認証と認可機能を実現するためのcore component
spring-security-web WebアプリケーションのSecurity対策を実現するためのcomponent
spring-security-config 各moduleから提供されているcomponentのsetupをsupportするためのcomponent

Spring Security Architecture

  1. client -> WebApplication request
  2. SpringSecurityのFilterChainProxyクラス(Servlet Filter)がリクエストを受け取り、HttpFirewall interfaceのmethodを呼び出してHttpServletRequestHttpServletResponseに対してfirewall機能を組み込む
  3. FilterChainProxyクラスは、SecurityFilterChainに設定されているsecurity対策用のsecurity fileterクラスに処理を委譲する
  4. SecurityFilterChainには複数のSecurity Filterが設定されていて、SecurityFilterの処理が正常に終了すると後続のSecurityFilterが実行される
  5. 最後のSecurityFilterの処理が正常に終了した場合、後続処理(ServletFilterやServletなど)を呼び出し、WebApplication内のリソースへアクセスする
  6. SecurityFilterChainクラスは、WebApplicationが返却したリソースをclientに返却する

spring security architecture

Authentication Process Flow

  1. clientは、認証処理を行うpathに対して資格情報(username/password/token)を指定してリクエストを送信
  2. AuthenticationFilterは資格情報を取得し、AuthenticationManagerclassの認証処理を呼び出す
  3. ProviderManagerは実際の認証処理をAuthenticationProvider interfaceの実装に委譲する
  4. DaoAuthenticationProviderは、UserDetailsServiceのユーザー情報取得処理を呼び出す
  5. UserDetailsServiceの実装classは、datasourceからユーザー情報を取得する
  6. UserDetailsServiceの実装classは、datasourceから取得したユーザー情報からUserDetailを生成する
  7. DaoAuthenticatorProviderは、UserDetailsServiceから返却されたUserDetailsとclientが指定した認証情報との照合を行い認証結果を返す
  8. AuthenticationFilterclassはAuthenticationManagerから返却された認証結果をhandlingする
    • 認証成功: AuthenticationSuccessHandlerにてhandling
    • 認証失敗: AuthenticationFailureHandlerにてhandling

authentication process flow

  • Authentication Filter
    • 認証方式に対する実装を提供するServletFilter
      • Basic認証ServletFilter
      • Digest認証ServletFilter
      • RememberMe認証ServletFilter
  • Authentication Manager
    • 認証処理を実行するためのinterface
    • default実装(ProviderManager): 認証処理はAuthenticationProviderに委譲し、AuthenticationProviderで行われた認証処理の結果をhandling
  • Authentication Provider
    • 認証処理を実装を提供するためのinterface

Authentication Event Handling

Spring Securityは、Spring Frameworkが提供しているEvent通知の仕組みを利用して、認証処理の処理結果を他のcomponentへ連携する仕組みを提供している.この機能を利用することで、以下のような機能を容易に実装することができる.

  • 認証成功or失敗などの認証履歴をdatabaseやログに保存したい
  • Passwordを連続して間違った場合、アカウントをロックしたい
  1. SpringSecurityの認証機能は、認証結果(認証情報や認証例外)をAuthenticationEventPublisherに渡して認証イベントの通知依頼を行う
  2. AuthenticationEventPublisher interfaceのdefaultの実装クラスは、認証結果に対応する認証Event classのinstanceを生成し、ApplicationEventPublisherに渡してEventの通知依頼を行う
  3. ApplicationEventPublisherinterfaceの実装は、ApplicatioinListenerinterfaceの実装classにeventを通知する
  4. ApplicationListenerの実装classの1つであるApplicationListenerMethodAdaptorは、@org.springframework.context.EventListenerが付与されているmethodを呼び出してEventを通知する

authentication event handling

Event Class Description
AuthenticationSuccessEvent AuthenticationProviderによる認証処理が成功したことを通知(後続の認証処理で失敗する可能性あり)
SessionFixationProtectionEvent Session固定攻撃対策の処理が成功したことを通知
InteractiveAuthenticationSuccessEvent 認証処理がすべて成功したことを通知
AuthenticationFailureBadCredentialsEvent BadCredentialsExceptionが発生したことを通知
AuthenticationFailureDisableEvent DisabledExceptionが発生したことを通知
...etc ...etc
@Component
public class AuthenticationEventListeners {
  private static final Logger log = LoggerFactory.getLogger(AuthenticationEventListeners.class);

  public void handleBadCredential(AuthenticationFailureBadCredentialsEvent event) {
    log.info("Bad credentials is detected. username: {}", event.getAuthentication().getName());
    // 任意の処理
  }
}

Authorization Process

  1. clientが任意のresourceにアクセス
  2. FilterSecurityInterceptorclassは、AccessDecisionManagerinterfaceのmethodを呼び出し、resourceへのアクセス権限の有無をチェックする
  3. AffirmativeBasedclassは、AccessDecisionVoterinterfaceのmethodの呼び出し、アクセス権限の有無を投票してもらう
  4. FilterSecurityInterceptorは、AccessDecisionManagerによってアクセス権限が付与された場合のみ、resourceへアクセスする

authorization process

  • FilterSeurityInterceptor
    • http requestに対して認可処理を適用するためのServletFilter
  • AccessDecisionManager
    • アクセスしようとしたresourceに対してアクセス権限があるかチェックを行うためのinterface
  • AccessDecisionVoter
    • アクセスしようとしたresourceに指定されているaccess policyを参照し、アクセス権を付与するか、投票(付与/拒否/棄権)するためのinterface
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
  @Autowired
  ReservationUserDetailsService userDetailsService;

  @Bean
  PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
  }

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests().antMatchers("/js/**", "/css/**").permitAll().antMatchers("/**").authenticated().and()
        .formLogin().loginPage("/loginForm").loginProcessingUrl("/login").usernameParameter("username")
        .passwordParameter("password").defaultSuccessUrl("/rooms", true).failureUrl("/loginForm?error=true")
        .permitAll();
  }

  @Override
  protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
  }
}

Discussion