인증 메커니즘
- 스프링 시큐리티는 보안 관련 요구사항들을 각각 필터 형태로 어플리케이션에 삽입하고, 사용자의 요청을 가로채서 보안적 역할을 한다.
1. AuthenticationFilter에 의해 사용자의 요청을 가로챈다.
사용자의 요청을 검증하는 인증 필터인 AuthenticationFilter가 AuthenticationManager에 의해 검증된다.
2.AuthenticationManager가 요청을 검증한다.
Filter에서 가로챈 요청을 AuthenticationManager은 사용자의 검증한다.
3. AuthenticationProvider 목록을 순회하며 검증에 필요한 특정 유행의 인증을 수행한다.
AuthenticationManager 는 다수의 AuthenticationProvider를 순회하며 검증에 필요한 특정 유행의 인증을 수행한다.
ex) 사용자 명/ 비밀번호 기반의 인증 형태를 가진 어플리케이션은, AuthenticationProvider 중 사용자명 / 비밀번호 형태의 인증을 수행하는 DaoAuthenticationProvider를, JWT 토큰 기반의 인증 형태를 가진 어플리케이션의 경우는 JwtAuthenticationProvider를 사용한다.
여기서 AuthenticationProvider은 인증을 수행하기 위해 사용자를 불러오기 위해 UserDetailService 가 필요하다.
- UserDetailService애는 loadUserByUserName() 메서드가 있다.
4. Authentication Provider는 회원정보를 호출하기 위해 UserDetailService 를 사용한다.
5. UserDetailService는 불러온 회원정보를 스프링 시큐리티가 사용할 수 있는 형태인 UserDetailservice 에 저장한다.
6. 저장된 회원정보를 담은 UserDetails 를 AuthenticationProvider에 반환한다.
7. 인증된 회원 정보를 SecurityContextHolder 내부에 저장한다. 인증에 실패하면 Exception 발생한다.
UserDetail
=> 스프링 시큐리티가 사용하는 회원정보
Spring Security에서 사용자 정보를 담는 인터페이스이자, 사용자 정보를 불러오기 위해서 구현해야 하는 인터페이스이다.
override 메소드 종류
public interface UserDetails extends Serializable {
Collection<? extends GrantedAuthority> getAuthorities();
String getPassword();
String getUsername();
boolean isAccountNonExpired();
boolean isAccountNonLocked();
boolean isCredentialsNonExpired();
boolean isEnabled()l
}
UserDetail를 구현한 대표적인 객체는 User가 있다.
User
public class User implements UserDetails, CredentialsContainer {
...
private String password;
private final String username;
private final Set<GrantedAuthority> authorities;
private final boolean accountNonExpired;
private final boolean accountNonLocked;
private final boolean credentialsNonExpired;
private final boolean enabled;
...
@Override
public Collection<GrantedAuthority> getAuthorities() {
return this.authorities;
}
@Override
public String getPassword() {
return this.password;
}
@Override
public String getUsername() {
return this.username;
}
@Override
public boolean isEnabled() {
return this.enabled;
}
@Override
public boolean isAccountNonExpired() {
return this.accountNonExpired;
}
@Override
public boolean isAccountNonLocked() {
return this.accountNonLocked;
}
@Override
public boolean isCredentialsNonExpired() {
return this.credentialsNonExpired;
}
@Override
public void eraseCredentials() {
this.password = null;
}
...
}
- User의 필드들은 final 키워드로 정의됨에 따라 생성자로 인해 객체가 생성되는 시점에만 값이 할당되도록 세팅되어 있다.
생성자로 인해 객체가 생성되는 시점에 필드의 값이 결정되고, 이후에 시스템에서 해당 객체의 필드 정보를 변경할 수 없어서 정보의 오염을 막을 수 있다.
UserDetailService
public interface UserDetailsService {
UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
}
loadUserByUsername()
UserDetailService의 가장 중요한 역할은, AuthenticationProvider 가 회원정보를 인증할 수 있도록 시스템 상으로 회원 정보를 불러오는 것이다. 이러한 역할을 처리하는 메소드이다.
- 일치하는 회원이 없다면 UsernameNotFoundException을 자신이 호출된 AuthenticationProvider으로 던진다.
참고한 블로그
'BACKEND > Spring Boot' 카테고리의 다른 글
[자바 ORM 표준 JPA 프로그래밍 - 기본편] 1일 차 JPA에 대해서 (4) | 2024.10.21 |
---|---|
Spring Container는 어떻게 생성될까 (0) | 2024.09.22 |
Tomcat은 어떻게 동작하는가 (0) | 2024.09.22 |
테스트 스텁과 목 오브젝트의 차이점 (1) | 2024.09.19 |
JWT 에 대해서 (0) | 2023.11.07 |
안녕하세오 저는 똑똑해지고 싶은 버그 수집가에오
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!