320x100
반응형
목차
- [이론] 스프링 시큐리티 1
- [이론] 스프링 시큐리티2
- [실습] 스프링 시큐리티 Form Login
- [추가] CustomAuthenticationProvider vs DaoAuthenticationProvider
- [이론] 스프링 시큐리티3
- [이론] 스프링 시큐리티4
- [추가] AuthorizeReqeusts vs AuthorizeHttpRequests
- [실습] 스프링 시큐리티 Json data Login 처리
- [실습] 스프링 시큐리티 JWT 설정
- [실습] 스프링 시큐리티 JWT 처리
- OAuth2
스프링 시큐리티란?
스프링 기반의 애플리케이션 보안(인증, 권한, 인가)를 담당하는 스프링 하위 프레임워크
- 인증: 접근하는 사용자가 누구인지 확인(현관문 벨을 눌렀을 때 '누구세요?'라고 묻기)
- 인가: 인증된 사용자에 대해서 권한을 확인하고 허락(누구인지 듣고 알고 있는 사람이라면 문 열어주기)
스프링 시큐리티 기본 동작 흐름도
기본적으로 인터페이스를 상속받아 기능을 구현을 한다
우선 지금은 UserDetailsService(사용자 세부 정보 서비스), PasswordEncoder에 대해서 알아본다
UserDetailsService
사용자 관리
- UserDetails
- 스프링 시큐리티에서 사용자를 정의하는 모델
- 스프링 시큐리티가 이해하는 방식으로 사용자를 나타내기 위한 모델
- 하나 이상의 권한(GrantedAuthority)을 가진다
- UserDetailsService
- 사용자 이름으로 검색하는 역할
- 인증을 완료하는데 있어서 반드시 필요한 유일한 작업
- 재정의 후 Bean 등록
- UserDetailsManager
- UserDetailsService 상속받아 추가적인 작업 수행 가능
- 사용자 추가, 수정, 삭제 작업
사용자를 인증하는 기능만 필요한 경우 UserDetailsService만 구현하면 필요한 기능을 제공할 수 있다
UserDetails
기능 목록
- getUsername()
- getPassword()
- getAuthorities()
- isAccountNonExpired()
- isAccountNonLocked()
- isCredentialsNonExpired()
- isEnabled()
데이터베이스 사용시 UserDetails 정의 방법
public class DbUser implements UserDetails {
private final User user;
public DbUser(User user) {
this.user = user;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return List.of(() -> user.getAuthority());
}
@Override
public String getPassword() {
return user.getPassword();
}
@Override
public String getUsername() {
return user.getUsername();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
UserDetailsService
public interface UserDetailsService {
UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
}
딱히 추가적인 기능은 없고 해당 사용자가 존재하는지 여부만 판별한다
UserRepository를 이용하여 사용자 존재 여부의 로직을 구현하면 된다
PasswordEncoder
암호 검증, 암호화 역할을 함
public interface PasswordEncoder {
String encode(CharSequence rawPassword); // 암호화
boolean matches(CharSequence rawPassword, String encodedPassword); // 검증
default boolean upgradeEncoding(String encodedPassword) { // 보안 향상을 위해 재 인코딩
return false;
}
}
제공되는 옵션
- NoOpPasswordEncoder: 암호화 하지 않음
- StandardPasswordEncoder: SHA-256 사용
- Pbkdf2PasswordEncoder: PBKDF2 사용
- BCryptPasswordEncoder: bcrypt 해싱 함수 사용
- SCryptPasswordEncoder: scrypt 해싱 함수 사용
여러 Encoder 사용시 설정 방법
DelegatingPasswordEncoder 사용
Map의 key 값을 접두사로 암호앞에 붙여서 사용
ex) {bcrypt}12345
@Bean
public PasswordEncoder passwordEncoder(){
Map<String, PasswordEncoder> encoders = new HashMap<>();
encoders.put("noop", NoOpPasswordEncoder.getInstance());
encoders.put("bcrypt", new BCryptPasswordEncoder());
encoders.put("scrypt", new SCryptPasswordEncoder());
return new DelegatingPasswordEncoder("bcrypt", encoders);
// return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
PasswordEncoder나 UserDetailsService를 직접 등록을 하나만 한 경우 오류가 나게 된다 필히 두개를 같이 등록해야 한다
320x100
반응형
'공부기록 > Spring Security' 카테고리의 다른 글
[이론] 스프링 시큐리티4 (0) | 2022.12.28 |
---|---|
[이론] 스프링 시큐리티3 (0) | 2022.12.26 |
[추가]CustomAuthenticationProvider vs DaoAuthenticationProvider (0) | 2022.12.22 |
[실습] 스프링시큐리티 로그인처리 (2) | 2022.12.21 |
[이론] 스프링 시큐리티2 (1) | 2022.12.21 |