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
springSecurityFilterChain
FilterChainProxy
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
에 저장,