본문 바로가기

Spring실습

Spring Security + jwt를 이용하여 로그인 구현하기(1)

반응형

드디어 spring security에 관하여 실습편을 작성하게 되었습니다.

저도 공부를 하다보니 이에 대하여 작성하는데 시간이 많이 소요되었습니다.

 

우선 이론편에서 말씀드린데로 

해당 Architecture에 맞추어 개발을 하였습니다.

https://pinlib.tistory.com/entry/Spring-security%EB%A1%9C-%ED%9A%8C%EC%9B%90%EA%B0%80%EC%9E%85-%EB%B0%8F-%EB%A1%9C%EA%B7%B8%EC%9D%B8-%EA%B5%AC%ED%98%84-%EC%9D%B4%EB%A1%A01

 

Spring security로 회원가입 및 로그인 구현 이론(1)

이번에 오랜만에 글을 쓰게 되었네요. 이번에 spring security를 사용하는게 처음이라 보니깐 여러가지 공부도 좀 하고 그러다 보니 글을 쓸 내용도 없었다가 이번에 어느정도 공부가 끝이 나게되어

pinlib.tistory.com

 

해당 사진의 경우 저의 spring security project structure입니다.

 

이번에 소개할 내용은 spring security의 중심이라고 생각되는

SpringSecurityConfig.java에 대하여 이야기해보겠습니다.

 

@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SpringSecurityConfig {

우선 크게 3개의 annotation을 사용합니다.

 

 * @RequiredArgsConstructor

기존에 DI를 주입하기 위해서는 constructor(생성자)나 Setter, Field 타입의 방식을 생성해야 했습니다.

하지만 lombok의 @RequiredArgsConstructor를 이용하면 초기화 되지 않은 final field의 생성자를 간단하게 만들어 줍니다.

 

* @EnableWebSecurity를 붙여 Spring Security를 활성화 시킵니다.

 

* @Configuration

해당 개념은 매우 중요하므로 조금 자세하게 설명해보겠습니다. (추후에 추가적인 글을 작성할 예정입니다.)

 

우선 bean의 개념을 알아야 하는데

bean의 경우 spring이 IoC(Inversion of Control(제어의 역전)) 방식으로 관리하는 object라는 뜻입니다. 

 

@Configuration의 경우 간단하게 말하자면 스프링 컨테이너에게 해당 annotation이 붙은 class가 bean 구성 class임을

알려줍니다.  또한 @Configuration안에 @Bean annotation을 사용하면 반복적으로 사용되는 복잡한 bean설정을 

독립시켜서 편리하게 재사용을 도와주는 모듈화를 쉽게 할 수 있습니다.

 

Spring Security를 위한 다른 코드들을 찾아 보신다면 securityConfig class에 WebSecurityConfigurerAdapter를

extend하여 사용하는 경우들이 매우 많을 것입니다.

허나, WebSecurityConfigurerAdapter의 경우 spring security 5.7.0 부터는 deprecated되었고 spring security 구버전을 사용할려고 하더라도 현재 사용중인 spring ver인 3.0.6을 이용할 수 없고 2점대 버전을 사용해야 하기 때문에 다른 방법들을

찾아 보느라고 시간이 좀 걸렸습니다.(정보가 너무 없었습니다.)

 

 

이제부터는 SpringSecurityConfig class 안에서 @Bean으로 등록해야 할 object들에 대하여 설명해보겠습니다.

@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
    return new BCryptPasswordEncoder();
}

jwt를 사용하기 위해서는 비밀번호를 암호화하기 위한 password encoder가 필요한데 

해당 code의 경우 BCrpy 인코딩을 통하여 비밀번호 암호화를 수행합니다.

 

@Bean
public SpringAuthenticationFilter customAuthenticationFilter() throws Exception {
    SpringAuthenticationFilter customAuthenticationFilter = new SpringAuthenticationFilter(authenticationManager());
    customAuthenticationFilter.setFilterProcessesUrl("user/login");
    customAuthenticationFilter.setAuthenticationSuccessHandler(customLoginSuccessHandler());
    customAuthenticationFilter.afterPropertiesSet();
    return customAuthenticationFilter;
}

사용자로부터 받은 정보를 바탕으로 UsernamePasswordAuthenticationToken을 발급받기 위한 filter로

필터의 url을 설정하고, 인증 과정 및 인증 후 처리에 대하여 설정합니다.

 

@Bean
public SpringLoginSuccessHandler customLoginSuccessHandler() {
    return new SpringLoginSuccessHandler();
}

filter에서의 인증 성공시의 처리를 위한 handler

 

@Bean
public SpringAuthenticationProvider customAuthenticationProvider() {
    return new SpringAuthenticationProvider(userDetailsService, bCryptPasswordEncoder());
}

provider에서는 userDetailsService를 통해 조회 및 검증한 정보화 비밀번호가 일치하는지 확인합니다.

 

@Bean
public AuthenticationManager authenticationManager() throws Exception {
    return new ProviderManager(Collections.singletonList(customAuthenticationProvider()));
}

추후에 보여드릴 SpringAuthenticationProvider.java의 authenticate의

인증 method를 도와주는 authenticationManager입니다.

 

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    http.csrf().disable().authorizeRequests()
            .anyRequest().permitAll()
            .and()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.ALWAYS)
            .and()
            .formLogin()
            .disable()
            .addFilterBefore(customAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
    return http.build();
}

해당 code의 경우 WebSecurityConfigurerAdapter이 deprecated되면서 사용하게 된 code입니다.

서버에 인증정보를 저장하지 않기에 csrf를 disable하고

token을 활용하는 경우 모든 요청에 대해 접근이 가능하도록 합니다.

또한 jwt token을 활용하면 session을 사용하지 않으므로 STATELESS로 설정한다.

그리고 form 기반의 로그인을 비활성화 합니다.

 

SpringSecurityConfig.java는 이정도로 마무리하고 다음 게시물에서는 

SpringAuthenticationFilter.java에 대하여 글을 써보겠습니다.

 

반응형