Spring Security

이상훈·2023년 4월 25일

Spring Security란?


인증, 인가, 보안기능을 담당하는 스프링 하위 프레임워크이다.
Spring Security는 '인증'과 '권한'에 대한 부분을 Filter 흐름에 따라 처리하고 있다.
ex. 로그인, 권한설정, 권한검사

서블릿 필터로 구현되어있다.

  • api를 호출할때 흐름


    서블릿 컨테이너는 그 사이 필터로 개입을 할 수 있다. 여기에 security filter도 넣어 보안기능을 수행한다.

    하지만 서블릿 컨테이너로 필터를 만들면 이 필터자체가 스프링 빈을 이해하지 못한다. 그래서 스프링에 위임한다.

    그걸 따라서 스프링은 security filter chain을 만든다.


    그래서 여기에는 여러 필터들이 있다.
    이 필터들의 묶음을 필터체인이라 부르고 각 필터들은 고유한 기능이 있다.
    기본적으로 설정하지 않아도 default로 등록되는 필터가 존재한다.
    공식문서 - 보안필터

  • security를 구현하는 방법은 다양하다.

    필터자체를 이해해서 필터를 구현할 것인지, 함수나 메서드를 오버라이딩해서 일부흐름만 커스터마이징할 것인지 구현방법은 사용자가 결정하기 나름이다.

WebSecurityConfigurerAdapter vs SecurityFilterChain


  • WebSecurityConfigureAdapter를 사용한 방식
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
 
    @Bean
    public UserDetailsService userDetailsService() {
        return new ShopmeUserDetailsService();
    }
 
    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
     
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/login").permitAll()
                .antMatchers("/users/**", "/settings/**").hasAuthority("Admin")
                .hasAnyAuthority("Admin", "Editor", "Salesperson")
                .hasAnyAuthority("Admin", "Editor", "Salesperson", "Shipper")
                .anyRequest().authenticated()
                .and().formLogin()
                .loginPage("/login")
                    .usernameParameter("email")
                    .permitAll()
                .and()
                .rememberMe().key("AbcdEfghIjklmNopQrsTuvXyz_0123456789")
                .and()
                .logout().permitAll();
 
        http.headers().frameOptions().sameOrigin();
    }
     
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/images/**", "/js/**", "/webjars/**"); 
    }
}
  • SecurityFilterChain를 사용한 방식
@Configuration
public class SecurityConfiguration {
 
    @Bean
    public UserDetailsService userDetailsService() {
        return new ShopmeUserDetailsService();
    }
 
    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
 
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
     
        http.authorizeRequests().antMatchers("/login").permitAll()
                .antMatchers("/users/**", "/settings/**").hasAuthority("Admin")
                .hasAnyAuthority("Admin", "Editor", "Salesperson")
                .hasAnyAuthority("Admin", "Editor", "Salesperson", "Shipper")
                .anyRequest().authenticated()
                .and().formLogin()
                .loginPage("/login")
                    .usernameParameter("email")
                    .permitAll()
                .and()
                .rememberMe().key("AbcdEfghIjklmNopQrsTuvXyz_0123456789")
                .and()
                .logout().permitAll();
 
        http.headers().frameOptions().sameOrigin();
 
        return http.build();
    }
 
    @Bean
    public WebSecurityCustomizer webSecurityCustomizer() {
        return (web) -> web.ignoring().antMatchers("/images/**", "/js/**", "/webjars/**");
    }
 
}

WebSecurityConfigurerAdapter가 없는 스프링 보안
해당 버전확인

HttpSecurity


HttpSecurity는 인증, 인가의 세부적인 기능을 설정할 수 있도록 API를 제공해주는 클래스이다.
공식문서 HttpSecurity 사용법

댕냥에 사용된 기능

  • .httpBasic() : 사용자 인증방법으로는 HTTP Basic Authentication을 사용한다.
    HTTP Basic Authentication

  • .csrf()
    csrf란?
    JWT를 사용하면 .csrf().disable()해도 될까?

  • .cos()란? CorsFilter사용할 를 추가합니다.
    .authorizeHttpRequests() : 특정 리소스의 접근 허용 또는 특정 권한을 가진 사용자만 접근을 가능하게 할 수 있습니다.
    AuthorizeRequests vs AuthorizeHttpRequests
    .permitAll() : 설정한 리소스의 접근을 인증절차 없이 허용한다는 의미 입니다.

  • .exceptionHandling()

    • AccessDeniedHandler
      • 인가 예외 처리를 담당
      • 서버에 요청을 할 때 액세스가 가능한지 권한을 체크후 액세스 할 수 없는 요청을 했을시 동작함
    • AuthenticationEntryPoint
      • 인증이 되지않은 유저가 요청을 했을때 동작함
  • .sessionManagement() : 세션 관리 기능이 작동함
    .sessionCreationPolicy(SessionCreationPolicy.STATELESS) : 스프링 시큐리티가 생성하지도 않고 존재해도 사용하지 않음
    SessionCreationPolicy.STATELESS 로 세션정책을 설정한다는것은 인증 처리 관점에서 스프링 시큐리티가 더 이상 세션쿠키 방식의 인증 메카니즘으로 인증처리를 하지 않겠다는 의미로 볼 수 있습니다.
    댕냥은 세션쿠키방식의 인증은 안하는걸까?

  • .addFilterBefore() : 지정된 필터 앞에 커스텀 필터를 추가
    인증을 처리하는 기본필터 UsernamePasswordAuthenticationFilter 대신 별도의 인증 로직을 가진 필터를 생성하고 사용하고 싶을 때 아래와 같이 필터를 등록하고 사용합니다.

  • .formLogin() : 로그인 페이지와 기타 로그인 처리 및 성공 실패 처리를 사용하겠다는 의미 입니다.

  • 댕냥에 admin 도전과제로 해도 좋을듯

Spring Security 모듈


2번 참고

Spring Security 처리 과정



Session 사용
JWT 사용

참고


https://www.youtube.com/watch?v=ewslpCROKXY
인프런 정수원 -springSecurity 유료강의 요약본(이건 그냥 첨부)

면접참고


  1. Spring Security - 기본지식
  2. Csrf

0개의 댓글