Spring Security 내부 흐름
Spring Security 내부 흐름
플로우 다이어그램
-
사용자가 웹 어플리케이션에 자격증명 정보를 입력한다. 이 정보는
Spring Security Filters(Spring Security Filter Chain)
으로 넘겨진다.Spring Security Filters
는 사용자가 입력한 자격증명을 가로채고, 접근 권한이 있는지 확인한다.Spring Security Filter Chain?
FIlter Chain에는
UsernamePasswordAuthenticationFilter
: 사용자 이름과 비밀번호를 통한 인증을 처리
BasicAuthenticationFilter
: HTTP Basic 인증을 처리
CsrfFilter
: CSRF 공격을 방지
LogoutFilter
: 로그아웃 요청을 처리
와 같은 필터들이 있을 수 있다. -
Spring Security Filters
는 엔드유저가 보낸 자격증명 정보에서 유저네임과 비밀번호를 추출하여Authentication
객체로 변환한다.Security Context
에 이미Authentication
정보가 존재하는 경우는 이후 해당 객체를 사용하고, 과정을 스킵한다.Authentication?
Authentication
객체는 스프링 시큐리티 프레임워크 안에서 엔드유저의 정보를 저장하기 위한 핵심 표준이다.
2단계에서는 유저네임와 자격증명만을 보유한다. 바로 다음과 같은 것들이다.
principal
: 사용자 이름 또는 사용자 식별자
credentials
: 사용자가 입력한 비밀번호
이후의 인증 과정에서 이Authentication
객체에는 더 많은 책임과 역할이 부여될 수 있다. -
Spring Security Filter
는 생성된 초기Authentication
객체를Authentication Manager
로 전달한다.Authentication Manager?
Authentication Manager
는 여러Authentication Provider
들과 협력하여 인증 과정을 수행한다:-
Athentication Provider
에 위임:Authentication Manager
는 실제 인증 작업을 여러Authentication Provider
에 위임한다. 각Authentication Provider
는 특정 인증 메커니즘을 담당한다. -
인증 결과 반환:
Authentication Provider
에서 인증이 성공하면,Authentication Manager
는 인증된Authentication
객체를 반환한다. 이 객체는 사용자에 대한 추가 정보(권한, 인증 여부 등)를 포함한다.
모든 Filter가
Authentication Manager
에게Authentication
객체를 넘겨주는 것은 아니다. 인증 작업을 담당하는UsernamePasswordAuthenticationFilter
나BasicAuthenticationFilter
에 의해 호출된다. 다른 필터들은 Authentication 객체를 만들지도 않는다. -
-
Authentication Provider
는Authentication
객체를 받아서 적절한 인증 절차를 수행한다. 인증이 성공하면Authentication
객체를 반환한다. 다음은 그 예시이다.- DaoAuthenticationProvider: 데이터베이스에서 사용자 정보를 조회하여 인증을 수행한다.
- LdapAuthenticationProvider: LDAP 서버를 통해 인증을 수행한다.
- JwtAuthenticationProvider: JWT 토큰을 사용하여 인증을 수행한다.
Provider가 반환하는 Authentication
Authentication Provider
가 인증 완료 후 반환하는 Authentication 객체에는 추가 정보가 포함된다. Principal, Credentials, Authorities, Details, Authenticated와 같은 정보가 포함된다. 추후UserDetialsService
에서 반환된 정보를 통해Provider
가UsernamePasswordAuthenticationToken
과 같은Authentication
의 자식 클래스를 사용하여 추가 정보를 넣는 것이다.만약
Provider
하나의 인증이 실패했다고 하더라도,Authentication Manager
는 곧바로 실패 응답을 반환하지 않는다. 가능한 모든Provider
를 호출한 뒤에야 비로소 실패 응답을 반환한다. -
UserDetailsService
는 사용자의 인증 정보를 로드하는 역할을 한다.@Service public class CustomUserDetailsService implements UserDetailsService { @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { // 데이터베이스나 다른 소스로부터 사용자 정보를 로드 if ("user".equals(username)) { return User.builder() .username(username) .password("{noop}password") // {noop}은 비밀번호를 암호화하지 않음을 나타냅니다 .authorities(Collections.singletonList(new SimpleGrantedAuthority("ROLE_USER"))) .build(); } else { throw new UsernameNotFoundException("User not found"); } } }
UserDetailsManager
인터페이스는UserDetailsService
를 확장하여 사용자의 추가적인 관리 기능을 제공한다. 이 인터페이스는 사용자의 생성, 수정, 삭제 등의 관리 기능을 포함한다.
하지만 회원 정보는 외부 DB에 저장하는 경우가 많기 때문에 따로 사용할 일은 적은 듯 하다. 보통 따로 CRUD API를 만들어 유저정보를 관리하는 것이 선호된다. -
Password Encoder
를 사용하여 패스워드 암호화,보통BCryptPasswordEncoder()
를 많이 사용함. -
인증 정보가 추가된
Autentication
객체를Authentication Manager
에게 반환 -
모든
Authentication Provider
에서 인증이 실패한 경우 실패 메시지 반환, 성공한 경우는Authentication
객체 반환 -
최종적으로 인증을 수행한 필터에서
Authentication
객체를Security Context
에 저장함.