spring security는 servlet filter및 aop기반이므로 장점이 비침투적이라는 것이다. 즉, 개발자가 짠 코드에 변경한다거나 구현한다거 삽입한다거나 할 필요가 없음
SecurityContext
Authentication 을 보관하는 역할로 SecurityContext를 통해 Authentication 객체를 꺼내올 수 있음Authentication 은getter/setter 뿐SpringContextHolder
SecurityContextHolder는 보안 주체의 세부 정보를 포함하여 응용 프로그램의 현재 보안 컨텍스트에 대한 세부 정보가 저장됩니다.UsernamePasswordAuthenticationToken
Authentication을 implements한 AbstractAuthenticationToken의 하위 클래스로 username이 Principal의 역할을 하고, password가 Credential의 역할을 합니다.public class UsernamePasswordAuthenticationToken extends AbstractAuthenticationToken {
// 주로 사용자의 username에 해당함
private final Object principal;
// 주로 사용자의 password에 해당함
private Object credentials;
// 인증 완료 전의 객체 생성
public UsernamePasswordAuthenticationToken(Object principal, Object credentials) {
super(null);
this.principal = principal;
this.credentials = credentials;
setAuthenticated(false);
}
// 인증 완료 후의 객체 생성
public UsernamePasswordAuthenticationToken(Object principal, Object credentials,
Collection<? extends GrantedAuthority> authorities) {
super(authorities);
this.principal = principal;
this.credentials = credentials;
super.setAuthenticated(true); // must use super, as we override
}
}ProviderManager


AuthenticationProvider
Authentication 객체를 받아서 인증이 완료된 객체를 반환하는 역할을 합니다.AuthenticationManager
인증에 대한 부분은 AuthenticationManager를 통해서 처리하게 되는데, 실질적으로는 AuthenticationManager에 등록된 AuthenticationProvider에 의해 처리됩니다.
인증이 성공하면 isAuthenticated=true 인 객체를 생성하여 SecurityContext에 저장합니다.
실패할 경우에는 AuthenticationException을 발생시킵니다.
DaoAuthenticationProvider는 AbstractUserDetailsAuthenticationProvider를 상속받아 실제 인증 과정에 대한 로직을 처리합니다.
AuthenticationManager에 DaoAuthenticationProvider를 등록하는 방법은 WebSecurityConfigurerAdapter를 상속해 만든 ApplicationSecurityConfig에서 할수 있습니다.
@Configuration
@EnableWebSecurity
public class ApplicationSecurityConfig extends WebSecurityConfigurerAdapter {
private final PasswordEncoder passwordEncoder;
@Autowired
public ApplicationSecurityConfig(PasswordEncoder passwordEncoder,) {
this.passwordEncoder = passwordEncoder;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(daoAuthenticationProvider());
}
@Bean
public DaoAuthenticationProvider daoAuthenticationProvider() {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setPasswordEncoder(passwordEncoder);
provider.setUserDetailsService(applicationUserService);
return provider;
}
}
UserDetails
UserDetails 객체는 UsernamePasswordAuthenticationToken을 생성하기 위해 사용됩니다.UserDetails 인터페이스의 경우 직접 개발한 CustomUserDetails에 UserDetails를 implements하여 사용하면 됩니다UserDetailsService
UserDetails 객체를 반환하는 단 하나의 메소드를 가지고 있는데, 일반적으로 이를 구현한 클래스의 내부에 UserRepository를 주입받아 DB에 연결하여 처리합니다.GrantedAuthority
ROLE_ADMIN, ROLE_USER와 같이 ROLE_의 형태로 사용됩니다.Reference
Spring Security의 서블릿 필터
DelegatingFilterProxy 를 이용

DelegatingFilterProxy 란?
Spring Security에서 DelegatingFilterProxy에 설정하는 서블릿 필터 bean
springSecurityFilterChainFilterChainProxy

public class FilterChainProxy extends GenericFilterBean {
private List<SecurityFilterChain> filterChains;
// ...
}
SPRING_SECURITY_SAVED_REQUEST<intercept-url /> 내용을 기준으로 권한 처리
유저가 로그인을 시도, http 요청이 들어옴
Authentication Filter가 http 서버를 request해서 사용자가 보낸 정보를 인터셉트 해 username,password를 조합하여 UsernamePasswordAuthenticationToken을 생성
UsernamePasswordAuthenticationToken는 Authentication을 implement한 구현체임UsernamePasswordAuthenticationToken을 인증을 담당할 AuthenticationManager에게 만들어서 위임시킴

AuthenticationProvider에 Authentication객체를 전달UserDetailsService에서 Authentication을 가지고 DB를 조회 일치 시 UserDetails객체를 꺼내서 UserSession을 생성UserDetails를 SecurityContextHolder에 저장,