본문 바로가기
Spring/Spring Security

[Spring Security] 시큐리티 폼 로그인 커스텀 설정

by 제우제우 2024. 9. 2.

PasswordEncorder

@Bean
public PasswordEncoder passwordEncoder(){
    return new BCryptPasswordEncoder();
}

 

비밀번호 암호화에 사용할 PasswordEncorder 빈 정의 

PasswordEncorder 인터페이스는 14개의 구현체를 제공한다.

 

BCryptPasswordEncorder는 BCrypt 알고리즘을 사용한다. 

예전에 스프링 시큐리티 비밀번호 암호화 모듈인 Crypto와 그중에서 ScyptEncorder를 정리했는데 참고하면 좋다. 

https://20240228.tistory.com/160

 

비밀번호 암호화 적용하기(Spring Security Crypto)

https://20240228.tistory.com/153 비밀번호 암호화목차암호화 종류단방향 암호화 방법단방향 암호화 문제점 개선 (+ Salt)단방향 암호화 문제점 개선 (+ Key Stretching)양방향 암호화 특징 참고 자료

20240228.tistory.com

 

 NoOpPasswordEncoder (@Deprecated

@Override
public String encode(CharSequence rawPassword) {
    return rawPassword.toString();
}

 

해당 PasswordEncorder는 비밀번호를 받아서 그대로 반환한다.

암호화 적용이 필요 없는 테스트 환경에서 사용  

@Deprecated가 붙었지만 사용이 중지될 예정은 없다고 한다. 

UserDetailsService

@Bean
public UserDetailsService userDetailService() {
    InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
    UserDetails user =
            User.withUsername("baejeu")
            .password(passwordEncoder().encode("1234"))
            .roles("ADMIN")
            .build();
    manager.createUser(user);
    return manager;
}

 

InMemoryUserDetailsManager: 메모리 내에서 사용자 정보를 관리하는 구현체

manager.createUser(user): 만든 사용자를 메모리 내 사용자 관리자에 추가

SecurityFilterChain

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception{
    return http
            .authorizeHttpRequests(
                    authorize -> authorize
                    .requestMatchers("/auth/login").permitAll()
                    .anyRequest().authenticated())
            .csrf(AbstractHttpConfigurer::disable) // (csrf -> csrf.disable())
            .formLogin(login -> login
                    .loginPage("/auth/login")
                    .loginProcessingUrl("/auth/login")
                    .usernameParameter("username")
                    .passwordParameter("password")
                    .defaultSuccessUrl("/")
            )
            .userDetailsService(userDetailService())
            .build();
}

 

formLogin: 폼 로그인을 설정

  • loginPage("/auth/login"):  커스텀 로그인 페이지 경로를 설정
  • loginProcessingUrl("/auth/login"): 로그인 처리 URL을 지정
  • usernameParameter("username") / passwordParameter("password"): 로그인 폼에서 사용자명과 비밀번호의 파라미터 이름을 설정
  • defaultSuccessUrl("/"): 로그인 성공 시 리디렉션할 기본 URL을 설정

userDetailsService(userDetailService()): 사용자 정보를 관리하는 서비스 설정을 연결 

전체 코드 & 테스트 코드 

@Configuration
@EnableWebSecurity(debug = true) // todo: 운영 환경에서는 사용 금지
public class SecurityConfig {
    
    // WebSecurityCustomizer 내용 생략 
    
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception{
        return http
                .authorizeHttpRequests(
                        authorize -> authorize
                        .requestMatchers("/auth/login").permitAll()
                        .anyRequest().authenticated())
                .csrf(AbstractHttpConfigurer::disable) // (csrf -> csrf.disable())
                .formLogin(login -> login
                        .loginPage("/auth/login")
                        .loginProcessingUrl("/auth/login")
                        .usernameParameter("username")
                        .passwordParameter("password")
                        .defaultSuccessUrl("/")
                )
                .userDetailsService(userDetailService())
                .build();
    }
    @Bean
    public UserDetailsService userDetailService() {
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        UserDetails user =
                User.withUsername("baejeu")
                .password(passwordEncoder().encode("1234"))
                .roles("ADMIN")
                .build();
        manager.createUser(user);
        return manager;
    }
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
}

 

HttpClient 테스트 

### 로그인

POST http://localhost:8080/auth/login
Content-Type: application/x-www-form-urlencoded

username=baejeu&password=1234

 

정상적으로 지정해둔 / 경로로 리다이렉션한다. 

POST http://localhost:8080/auth/login

Redirections:
-> http://localhost:8080/