💡 Processing Flow
- 1. User의 로그인 시도, Request를 제일 먼저 만나는 컴포넌트 - UsernamePasswordAuthenticationFilter
Login Form 방식의 로그인 시 사용
- 2. ID, PW를 전달받은 UsernamePasswordAuthenticationFilter는 UsernamePasswordAuthenticationToken을 생성
* UsernamePasswordAuthenticationFilter는 AbstractAuthenticationProcessingFilter를 상속한다.
UsernamePasswordAuthenticationToken은 Authentication 인터페이스의 구현체이다 - 3. 인증이 되지않은 Authentication을 AuthenticationManager 인터페이스를 구현한 ProviderManager에게 전달
- 4. ProviderManager -> AuthenticationProvider로 인증이 되지않은 Authentication 전달
- 5. UserDetailsService를 이용해 UserDetails를 구현한 User의 Credential 조회
UserDetails는 DB에 저장된 사용자의 Credential인 PW, 권한 정보를 포함하는 컴포넌트이고,
그 UserDetails를 제공하는 컴포넌트가 UserDetailService이다 - 6. DB에서 조회한 사용자의 Credential을 기반으로 UserDetails를 생성 후, AuthenticationProvider에게 전달
- 7. UserDetails를 전달받고 PasswordEncoder를 이용해
UserDetails의 PW와 Authentication의 PW가 일치하는지 검증 - 8. 인증에 성공하면 UserDetails를 이용해 인증된 Authentication 생성 후 ProviderManager에게 전달
인증에 실패하면 Exception을 발생시키고 인중 중단 - 9. 인증된 Authentication을 AuthenticatinFilter로 전달
- 10. SecurityCOntextHolder를 이용해 SecurityContext에 인증된 Authentication을 저장함
그리고 SecurityContext는 Spring Security의 정책에 따라 HttpSession에 저장된,
사용자의 인증 유지 or Stateless 유지
// 로그인 폼 방식을 사용할 때 사용하는 필터
// Filter의 doFilter()는 상속받은 AbstractAuthenticationProcessingFilter에 존재함
public class UsernamePasswordAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
// 클라이언트의 로그인 폼을 통해 전송되는 Request Parameter의 Default Username & Password이다
private static final String SPRING_SECURITY_FORM_USERNAME_KEY = "username;";
private static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "password";
// 클라이언트의 URL에 매치되는 Matcher
// AbstractAuthenticationProcessingFilter에 전달되어 Filter가 구체적 작업을 수행할지 다른 Filter를 호출할지 결정
private static final AntPathRequestMatcher DEFAULT_ANT_PATH_REQUEST_MATCHER = new AntPathRequestMatcher("/login", "POST");
// Matcher와 AuthenticationManager를 AbstractAuthenticationProcessingFilter에게 전달
public UsernamePasswordAuthenticationFilter(AuthenticationManager authenticationManager) {
super(DEFAULT_ANT_PATH_REQUEST_MATCHER, authenticationManager);
}
// 클라이언트에서 전달한 Username & Password를 이용해 인증을 시도하는 메서드
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
// HTTP 메서드가 Post가 아니면 throw Exception
if (this.postOnly && !request.getMethod().equals("POST")) {
throw new AuthenticationServiceException("Authentication Method Not Supported: " + request.getMethod());
}
String username = obtainUsername(request);
String password = obtainPassword(request);
// 클라이언트에서 전달한 Username & Password를 이용해 토큰 생성
UsernamePasswordAuthenticationToken authRequest = UsernamePasswordAuthenticationToken.unauthenticated(username, password);
// AuthenticationManager의 authenticate() 메서드를 이용해 인증 처리 위임
return this.getAuthenticationManager().authenticate(authRequest);
}
}
복습
> ## 📌 인증 구조
1. 로그인 요청 -> UsernamePasswordAuthenticationFilter가 받음
2. UsernamePasswordAuthenticationFilter가 UsernamePasswordAuthenticationToken 생성
(이 토큰은 Authentication을 구현한 클래스이며 인증이 되지않은 Authentication임)
3. 필터가 Authentication을 AuthenticationManager(인증처리 총괄)에게 전달
(ProviderManager = AuthenticationManager의 구현클래스, 인증 위임 총괄)
4. ProviderManager가 AuthenticationProvider에게 인증이 되지않은 Authentication 전달
5. AuthenticationProvider가 UserDetailsService를 이용해 UserDetails 조회
(UserDetails는 DB등의 저장소에 저장된 유저의 정보를 담고있는 컴포넌트)
6. DB에서 조회한 유저의 정보,크리덴셜 등으로 UserDetails를 생성 후 AuthenticationProvider에게 다시 전달
7. UserDetails를 받은 AuthenticationProvider는 PasswordEncoder를 이용해 (UserDetails의 PW == Authentication의 PW)를 검증, 인증에 실패 시 Exception throw
8. AuthenticationProvider는 인증된 Authentication을 ProviderManager에게 전달
(principal, credential, grantedAuthorities를 가지고 있는 Authentication)
9. 인증된 Authentication을 UsernamePasswordAuthenticationFilter에게 전달
10. SecurityContextHolder를 이용해 SecurityContext에 인증된 Authentication 저장
'Framework > Spring' 카테고리의 다른 글
Spring EL 접근 제어 표현식 (0) | 2022.11.21 |
---|---|
Authorization (0) | 2022.11.21 |
Servlet Filter Chain & DelegatingPasswordEncoder (0) | 2022.11.20 |
Spring Security 기본 구조 (0) | 2022.11.18 |
Cookie & Session & 웹 보안 공격 & CA 발급/HTTPS 적용 (0) | 2022.11.17 |