인증(Authentication)
인가(Authorization)
Principal
을 아이디로, Credential
을 비밀번호로 사용하는 Credential 기반의 인증 방식 을 사용합니다.
- Principal(접근 주체) : 보호 받는 리소스에 접근하는 대상
- Credential(비밀번호) : 리소스에 접근하는 대상의 비밀번호
Authentication
Authentication
은 현재 접근하는 주체의 정보와 권한을 담는 인터페이스입니다.SecurityContext
에 저장되며, SecurityContextHolder
를 통해 SecurityContext
에 접근하고, SecurityContext
를 통해 Authentication
에 접근할 수 있습니다.SecurityContext
Authentication
을 보관하는 역할을 하며, SecurityContext
를 통해 Authentication
객체를 꺼내올 수 있습니다.SecurityContextHolder
SecurityContextHolder
는 보안 주체의 세부 정보를 포함하여 응용 프로그램의 현재 보안 컨텍스트에 대한 세부 정보가 저장됩니다.Spring Security에서의 인증 처리 과정
username
과 password
를 조합해서 UsernamePasswordAuthenticationToken
인스턴스를 만듭니다.AuthenticationManager
의 인스턴스로 전달됩니다.AuthenticationManager
는 인증에 성공하면 Authentication
인스턴스를 리턴합니다.Authentication
인스턴스는 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
}
}
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
인터페이스의 경우 직접 개발한 ApplicationUser
에 UserDetails
를 implements하여 사용하면 됩니다UserDetailsService
UserDetails
객체를 반환하는 단 하나의 메소드를 가지고 있는데, 일반적으로 이를 구현한 클래스의 내부에 UserRepository
를 주입받아 DB에 연결하여 처리합니다.GrantedAuthority
ROLE_ADMIN
, ROLE_USER
와 같이 ROLE_
의 형태로 사용됩니다.