SpringBoot SpringSecurity 설정 v2-1. securityConfig 설정

jeonbang123·2023년 4월 15일
0

springboot

목록 보기
10/14
  • SpringBoot SpringSecurity 설정 v2-1. securityConfig 설정
  • SpringBoot SpringSecurity 설정 v2-2. UserDetails, UserDetailsService 설정
  • SpringBoot SpringSecurity 설정 v2-3. UsernamePasswordAuthenticationFilter 설정
  • SpringBoot SpringSecurity 설정 v2-4. BasicAuthorizationFilter 설정

1. dependency 추가

pom.xml

<!-- 4. Spring Security -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-security</artifactId>
</dependency>

2. SecurityConfig 설정

securityConfig.java

package com.codesign.base.configure;

import com.codesign.base.jwt.JwtAuthenticationFilter;
import com.codesign.base.jwt.JwtAuthorizationFilter;
import com.codesign.base.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private final UserService userService;  

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable(); // 위변조 방지 미사용
        http.cors().configurationSource(corsFilter()) // cors설정
                .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) // session 미사용
                .and().formLogin().disable() // formlogin 미사용
                .httpBasic().disable() // Baerer 사용으로 Basic방식 미사용
                // 다음 단계에서 설정 임시 주석처리
                // .addFilter(new JwtAuthenticationFilter(authenticationManager()))
                // .addFilter(new JwtAuthorizationFilter(authenticationManager(), userService))
                .authorizeRequests()
                .antMatchers("/api/v1/user/**").permitAll()
                .antMatchers("/api/v1/manager/**").access("hasRole('ROLE_MANAGER')")
                .anyRequest().permitAll();
    }

    @Bean
    public CorsConfigurationSource corsFilter(){
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true); // 자바스크립트 응답을 처리할 수 있게 할지 설정(ajax, axios)
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/api/*", config);
        // TODO /api/* 으로 요청이 왔을때, Allowed 된 요청만 받는지 확인하기

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

}

configure(HttpSecurity http)

속성
설명
csrf().disable()위변조 방지 미사용 >> 토큰 방식 사용
cors().configurationSource(corsFilter())corsFilter 설정
sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) /session 미사용 >> 토큰 방식 사용
formLogin().disable()로그인 폼 미사용 >> UsernamePasswordAuthenticationFilter 미동작 따로 필터등록 필요함
formLogin()을 사용하게 되면 서버로 로그인 요청시, username과 password로 인증하는 로직(UserDetailsService)을 수행하고, 세션에 저장한다. >> 토큰 발급할 것이므로 비활성
httpBasic().disable()httpBasic방식 미사용 >> Bearer방식 사용
authorizeRequests()권한설정 시작
antMatchers("/api/v1/user/**")해당 path에 관한 권한 설정
permitAll()모두 허용
access("hasRole('ROLE_MANAGER')")MANAGER만 허용

csrf().disable()
CSRF의 취약점은 공격자가 사용자가 의도하지 않는 요청을 수행하게 하는 취약점입니다. 즉 공격자는 사용자가 가지고 있는 권한 범위 내에서 악의적인 행위를 할 수 있습니다. 일반적으로 해당 권한은 쿠키와 세션을 이용해서 인증을 하고 있기 때문에 발생하는 일입니다.
하지만 Rest API를 이용한 서버라면, session 기반 인증과는 다르게 stateless하기 때문에 서버에 인증 정보를 보관하지 않습니다. 일반적으로 jwt 같은 토큰을 사용하여 인증하기 때문에 해당 토큰을 Cookie에 저장하지 않는다면 csrf 취약점에 대해서는 어느 정도 안전하다고 말할 수 있습니다.

httpBasic().disable()
세션방식에서 로그인시, 웹브라우저 쿠키에 세션ID 저장, 요청시, 헤더에 쿠키(세션아이디)를 들고감

그래서 동일 도메인에서만 허용하도록 httpOnly를 사용 - ajax나 axios로 요청시, 쿠키를 담아서 보내면 거부하는 기능

httpOnly : http요청이 아니면 쿠키를 건드릴 수 없게함, 아마 SSR으로 추측됨..
http요청이 아닌것 : 스크립트 파일에서.. fetch() . ajax, axios, 이거는 Rest Api 서버로 추측

그래서 요청시 인증하기 위해 나온게(as-is: JSESSION? , to-be: Authentication)
인증시 headers.Authorization에 인증정보를 담고가는 2가지 방식이 있다.

  1. header에 Authorization에 ID와 패스워드를 담는 방식 >> httpBasic 방식
  • 암호화 안됨 중간에 탈퇴 위혐 > https 서버를 사용해야함
  1. 토큰을 담는 방식 (JWT)>> Bearer 방식
  • 노출이 되면 안되지면 id, password 보다 안전
  • 서버쪽에서 계속 새로 만들어줌, 만료시간 이후 재생성

corsFilter()

속성
설명
setAllowCredentials(true)자바스크립트 응답을 처리 (ajax, axios)
addAllowedOrigin("*")모든 도메인, 포트 허용
addAllowedHeader("*")모든 Header허용 - 다른 커스텀 헤더
addAllowedMethod("*")모든 요청 허용 - GET, POST, PATCH, DELETE
source.registerCorsConfiguration("/api/*", config)해당 경로로 요청시 적용
  • 스프링 버전이 올라가면서 .allowedCredentials(true) 와 .allowedOrigins("*") 를 동시에 사용할 수 없도록 변경되었다고 한다.

참고
https://www.youtube.com/watch?v=GEv_hw0VOxE&list=PL93mKxaRDidERCyMaobSLkvSPzYtIk0Ah
https://kchanguk.tistory.com/197

profile
Design Awesome Style Code

0개의 댓글