BE전문가 프로젝트

4-4 Authentication(인증) - SecurityConfig 본문

SpringBoot Security

4-4 Authentication(인증) - SecurityConfig

원호보고서 2023. 7. 9. 20:22

Security를 설정하기 전 SpringBoot의 버전에 따라 설정 방법이 다르다.

3.XX 이상의 버전에서는 WebSecurityConfigurerAdapter 지원을 하지 않기 때문에 Bean으로 security 설정을 해줘야한다.

필자는 2.61 버전을 사용중이기 때문에 WebSecurityConfigurerAdapter를 사용하였다.

 

SecurityConfig

@Slf4j
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SpringConfig extends WebSecurityConfigurerAdapter {

    private final JwtService jwtService;

    private final CorsConfig corsConfig;

    private final AuthenticationEntryPointImpl authenticationEntryPointImpl;

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().mvcMatchers( "/", "/common/**");
        web.ignoring().requestMatchers(PathRequest.toStaticResources().atCommonLocations()); // 정적인 리소스들에 대해서 시큐리티 적용 무시.
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {

        http.addFilterBefore(new BeforeFilter(), BasicAuthenticationFilter.class);
        http.csrf().disable();
        http    .addFilter(corsConfig.corsFilter())                                             //인증(O), security Filter에 등록
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)     //세션 사용 x
                .and()
                .formLogin().disable()
                .httpBasic().disable()
                .addFilter(authenticationFilter())
                .authorizeRequests()

                .antMatchers("**/user/**")
                .access("hasRole('ROLE_USER') or hasRole('ROLE_MANAGER') or hasRole('ROLE_ADMIN')")
                .antMatchers("**/manager/**")
                .access("hasRole('ROLE_MANAGER') or hasRole('ROLE_ADMIN')")
                .anyRequest().permitAll()

                .and()
                .exceptionHandling()
                .authenticationEntryPoint(authenticationEntryPointImpl);

    }


    public UsernamePasswordAuthenticationFilter authenticationFilter() throws Exception{

        JwtAuthenticationFilter authenticationFilter = new JwtAuthenticationFilter(jwtService, authenticationManager());
        authenticationFilter.setFilterProcessesUrl("/login");
        return authenticationFilter;
    }
}

 

@EnableWebSecurity

Security를 적용하려면 해당 Annotation을 사용하여야하며 EnableWebSecurity에 마우스를 올려보면 

WebSecurityConfiguration.class, SpringWebMvcImportSelector.class, OAuth2ImportSelector.class, HttpSecurityConfiguration.class들을 import하는 것을 알 수 있다.

 

인증 및 인가가 필요하지 않는 path 설정

@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().mvcMatchers( "/", "/common/**");
    web.ignoring().requestMatchers(PathRequest.toStaticResources().atCommonLocations()); // 정적인 리소스들에 대해서 시큐리티 적용 무시.
}

해당 설정을 해주지 않는다면 index페이지 및 인증이 필요하지 않은 서비스 또한 인증 과정을 거쳐야 하기 때문에 설정을 해줘야한다.

 

※주의

정적인 요소(css, image 등) 또한 해당 설정을 하지 않는다면 인증과정을 거쳐야만 접근이 가능하기 때문에 설정을 해줘야하는데 SpringBoot에서 제공해주는 기본 경로에 정적 요소들을 보관해야 인식되며 그렇지 않은 경우 경로를 따로 지정해줘야한다.

 

 

Security 설정

@Override
public void configure(HttpSecurity http) throws Exception {

    http.addFilterBefore(new BeforeFilter(), BasicAuthenticationFilter.class);
    http.csrf().disable();
    http    .addFilter(corsConfig.corsFilter())                                             //인증(O), security Filter에 등록
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)     //세션 사용 x
            .and()	
            .formLogin().disable()		// Security에서 제공하는 form로그인 사용 X	
            .httpBasic().disable()		// Http basic Auth  기반으로 로그인 인증창사용 X										
            .addFilter(authenticationFilter())	// 인증 필터 적용
            
            .authorizeRequests()
            .antMatchers("**/user/**")
            .access("hasRole('ROLE_USER') or hasRole('ROLE_MANAGER') or hasRole('ROLE_ADMIN')")
            .antMatchers("**/manager/**")
            .access("hasRole('ROLE_MANAGER') or hasRole('ROLE_ADMIN')")
            .anyRequest().permitAll()

            .and()
            .exceptionHandling()
            .authenticationEntryPoint(authenticationEntryPointImpl);

}

 

Csrf 공격 차단

http.csrf().disable();

 

csrf 를 직역하자면 사이트 간 요청 위조라고 할 수 있으며 공격자가 사용자의 의도와는 상관없이 수정, 삭제, 등록 등을 특정 웹사이트에 요청하게 하는 공격을 말한다.

 

 

접근 권한 설정

.authorizeRequests()
.antMatchers("**/user/**")
.access("hasRole('ROLE_USER') or hasRole('ROLE_MANAGER') or hasRole('ROLE_ADMIN')")
.antMatchers("**/manager/**")
.access("hasRole('ROLE_MANAGER') or hasRole('ROLE_ADMIN')")
.anyRequest().permitAll()

 

path에 따라 권한을 설정하였으며 사용자의 권한에 따라 접근할 수 있는 서비스를 설정해준다.

 

 

ErrorHandle

.and()
.exceptionHandling()
.authenticationEntryPoint(authenticationEntryPointImpl);

인증 실패 및 에러가 나게 되면 실행되는 메소드를 설정

 

 

인증 필터 method

public UsernamePasswordAuthenticationFilter authenticationFilter() throws Exception{

    JwtAuthenticationFilter authenticationFilter = new JwtAuthenticationFilter(jwtService, authenticationManager());
    authenticationFilter.setFilterProcessesUrl("/login");
    return authenticationFilter;
}

/login을 요청하게 되면 실행되며 filter를 return해준다.

 

여기까지가 Jwt를 이용한 인증에 대한 포스팅이였으며 인가에 대한 설명은 다음 포스팅에서 하도록 하겠습니다.

 

성공

실패

Comments