Post

시큐리티 설정





참고





스프링 시큐리티의 설정

설정 방식에는 다음과 같이 두 가지가 있다.

  • java config
  • xml config

예전에는 설정 클래스에 WebSecurityConfigurerAdapter를 상속받아 메서드를 오버라이드하는 방식을 사용했다. 근데, 최근 버전부터는 WebSecurityConfigurerAdapter가 deprecate 되었다. 이제는 필요한 빈을 정의하는 방식으로 바뀌었다.



EnableWebSecurity

  • Spring Security와 Spring MVC integrating하기 위한 어노테이션이다. 설정 어노테이션 위에 붙는다.
  • 얘를 까보면 여러 설정 클래스들을 import하고 있는걸 볼 수 있다.
    • WebSecurityConfiguration.class
    • SpringWebMvcImportSelector.class
    • OAuth2ImportSelector.class
    • HttpSecurityConfiguration.class
  • 각각의 설정 클래스들은 설정에 필요한 빈들을 정의하고 있다.









시큐리티 설정 예시

나중에 참고할 수 있도록 시큐리티 설정을 기록해둘 생각이다. 코딩하다가 생각나면 계속 조금씩 추가할 예정.



PasswordEncoder

1
2
3
4
@Bean
public PasswordEncoder passwordEncoder() {
    return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
  • PasswordEncoder는 패스워드의 암호화와 검증 등의 역할을 하는 인터페이스다.
  • 기본적으로 BCryptEncoder가 사용된다.



SecurityFilterChain

1
2
3
4
5
6
7
8
9
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    http
        .csrf().disable()
        .authorizeHttpRequests()
        .antMatchers("/").permitAll();

    return http.build();
}



InMemoryUserDetailsManager

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Bean
public InMemoryUserDetailsManager userDetailsManager() {
    UserDetails user = User.withUsername("user")
            .password(passwordEncoder().encode("password"))
            .roles("USER")
            .build();

    UserDetails admin = User.withUsername("admin")
    .password(passwordEncoder().encode("password"))
    .roles("ADMIN")
    .build();

    return new InMemoryUserDetailsManager(user, admin);
}
  • 개발시에 사용할 인메모리 유저를 만들 수 있다.
  • 인메모리 계정을 생성하면 서버를 띄울 때마다 임시로 만들어주던 user 계정이 생성되지 않는다.



SecurityFilter

  • 커스텀 시큐리티 필터를 직접 만들고 싶을 때가 있을 것이다.
1
2
3
4
5
6
7
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    http
        .addFilterAt(customFilter, baseFilter.class);

    return http.build();
}
  • 필터는 순서가 중요하기 때문에 어느 위치에 넣을 것인가로 메서드가 나눠져 있다.
    • addFilterAt(Filter filter, Class<? extends Filter> atFilter)
      • atFilter의 순번에 filter가 들어가게 된다.
      • 같은 순서로 필터를 여러 개 등록할 수 없기 때문에 기존 필터는 등록하지 않아야 한다.
    • addFilterBefore()
      • atFilter의 바로 앞의 순번에 filter가 들어가게 된다.
    • addFilterAfter()
      • atFilter의 바로 뒤의 순번에 filter가 들어가게 된다.
    • addFilter(Filter filter)
      • filter의 수퍼 클래스를 고려하여 순서를 정해준다.



이거 이상해요 필터가 두 번씩 호출돼요

  • 커스텀 필터을 빈으로 등록하고 + 설정 파일에서 필터를 등록해줬다면 = 2번 들어가게 된다.
    • 스프링은 Filter를 구현한 스프링 빈을 Servlet context에 자동으로 추가시킨다.
    • 그 때문에 스프링 빈은 1개만 등록이 제대로 됐겠지만 Servlet Filter로써 한 번, Spring Security Filter로써 한 번 이렇게 두 번 호출된다.
    • 커스텀 필터 위의 @Component를 떼면 된다.



AuthenticationManager

1
2
3
4
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
    return authenticationConfiguration.getAuthenticationManager();
}
  • 다른 설정에 따라서 AuthenticationManager를 스프링이 자동으로 빈으로 등록해두는 경우가 있으니 주의해야 한다.
  • 이런 식으로 만들면 스프링이 만들어준걸 쓰는 것이기 때문에, 원치 않는 프로바이더가 들어가 있다.
1
2
3
4
@Bean
public AuthenticationManager authenticationManager() {
		return new ProviderManager(providers...);
}
  • 그래서 나는 이렇게 만들었는데, 아직까지는 문제가 없었다.





This post is licensed under CC BY 4.0 by the author.