Spring Security flow

  1. 사용자 입력 인증 정보 (User Entered Credentials)
    사용자가 제공하는 인증 정보는 로그인 과정의 첫 번째 단계입니다. 일반적으로 사용자 이름과 비밀번호가 포함됩니다.

public class LoginRequest {
    private String username;
    private String password;

    // getters and setters
}
  1. 인증 필터 (Authentication Filter)
    인증 필터는 사용자가 입력한 인증 정보를 필터링하고, Authentication 객체를 생성하는 역할을 합니다. 이 객체는 인증 매니저로 전달되어 사용자 인증을 시도합니다.
public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
    
    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) {
        String username = request.getParameter("username");
        String password = request.getParameter("password");

        UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
        return this.getAuthenticationManager().authenticate(authRequest);
    }
}
  1. 인증 매니저 (Authentication Manager)
    인증 매니저는 인증 요청을 관리하고, 실제 인증 로직을 실행합니다. 이 과정에서 여러 AuthenticationProvider를 사용하여 다양한 인증 방법을 처리합니다.
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.addFilter(new JwtAuthenticationFilter(authenticationManager()));
    }
}
  1. 인증 제공자 (Authentication Provider)
    인증 제공자는 사용자의 인증 정보를 검증하는 로직을 포함하고 있습니다. 주로 UserDetailsService와 함께 사용되어 사용자의 정보를 기반으로 인증을 처리합니다.
@Service
public class CustomAuthenticationProvider implements AuthenticationProvider {

    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String username = authentication.getName();
        String password = (String) authentication.getCredentials();

        UserDetails userDetails = userDetailsService.loadUserByUsername(username);
        if (userDetails != null && passwordEncoder.matches(password, userDetails.getPassword())) {
            return new UsernamePasswordAuthenticationToken(userDetails, password, userDetails.getAuthorities());
        }
        throw new BadCredentialsException("Invalid username or password");
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return authentication.equals(UsernamePasswordAuthenticationToken.class);
    }
}
  1. 사용자 정보 서비스 (User Details Service)
    사용자 정보 서비스는 데이터베이스에서 사용자의 정보를 가져오는 역할을 합니다. 이 서비스는 UserDetails 객체를 반환하여 인증 과정에서 사용됩니다.

@Service
public class CustomUserDetailsService implements UserDetailsService {

    @Autowired
    private UserRepository userRepository;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.findByUsername(username)
                .orElseThrow(() -> new UsernameNotFoundException("User not found"));
        return new CustomUserDetails(user);
    }
}
  1. 비밀번호 인코더 (Password Encoder)
    비밀번호 인코더는 비밀번호를 안전하게 인코딩하고 검증하는 데 사용됩니다. 이를 통해 비밀번호가 안전하게 저장되고 처리될 수 있습니다.
@Bean
public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
}
  1. 보안 컨텍스트 (Security Context)
    보안 컨텍스트는 인증된 사용자의 정보를 저장하고 관리하는 역할을 합니다. Spring Security는 현재 사용자의 인증 정보를 유지하기 위해 이 컨텍스트를 사용합니다.
SecurityContext context = SecurityContextHolder.getContext();
Authentication auth = context.getAuthentication();