아카이브

[스프링 기반 REST API 개발] 시큐리티 기본 설정하기 본문

Spring/스프링 기반 REST API 개발

[스프링 기반 REST API 개발] 시큐리티 기본 설정하기

주멘이 2021. 1. 9. 13:07

시큐리티 필터를 적용하기 않음

  • /docs/index.html

로그인 없이 접근 가능

  • GET /api/events
  • GET /api/events/{id}

로그인해야 접근 가능

  • 나머지 다
  • POST /api/events
  • PUT /api/events/{id}
  • ...

스프링 시큐리티 OAuth 2.0

  • AuthorizationServerOAuth2 토큰 발행(/oauth/token) 및 토큰 인증(/oauth/authorize)
    • Oder 0 (리소스 서버보다 우선순위가 높다.)
  • ResourceServer: 리소스 요청 인증 처리 (OAuth2 토큰 검사)
    • Oder 3 (이 값은 현재 고칠 수 없음)

스프링 시큐리티 설정

@EnableWebSecurity, @EnableGlobalMethodSecurity

extends WebSecurityConfigurerAdapter

  • SecurityConfig @Configuration class에서 설정
  • 설정하는 순간, 스프링 부트가 제공하는 자동 설정은 더 이상 제공되지 않음(커스터마이징 활성화)
  • WebSecurityConfigurerAdapter를 상속받은 커스텀 설정을 빈으로 등록하면 스프링 부트의 기본 시큐리티 설정은 사용하지 않게 된다.
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {}

PasswordEncoder: PasswordEncoderFactories.createDelegatingPassworkEncoder()

  • 다양한 인코딩 타입을 지원하며, 인코딩 타입을 PREFIX로 붙여준다.

PasswordEncoderFactories

 

    @Bean
    public PasswordEncoder passwordEncoder() {
        return PasswordEncoderFactories.createDelegatingPasswordEncoder();
    }

TokenStore: InMemoryTokenStore

    @Bean
    TokenStore tokenStore() {
        return new InMemoryTokenStore();
    }

AuthenticationManagerBean

  • 다른 AuthorizationServer나 ResourceServer가 참조할 수 있도록 Bean으로 등록
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

configure(AuthenticationManagerBuidler auth)

AuthenticationManager를 재정의

  •  userDetailsService : accountService를 적용한다
  •  passwordEncoder
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(accountService)
                .passwordEncoder(passwordEncoder);
    }

configure(WebSecurty web)

스프링 시큐리티 필터를 타기 전에 적용된 패턴을 걸러내서 서버 부하를 줄일 수 있다.(정적 리소스들을 걸러 줄 것을 권장)

PathRequest.toStaticResources() 사용하기

  •  ignore
    •  /docs/**
    •  /favicon.ico
    /* filter를 적용할지 말지 결정  (Http로 가기전에, WebSecurity를 적용할지 말지)- static resource 허용하기*/
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().mvcMatchers("/docs/index.html");
        web.ignoring().requestMatchers(PathRequest.toStaticResources().atCommonLocations());
    }

configure(HttpSecurity http)

스프링 시큐리티는 허용하면서(필터체인 안으로) HTTP로 거른다.

  •  /docs/**: permitAll
    /* filterchain 안에서 거르기*/
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .anonymous()
                .and()
                .formLogin()
                .and()
                .authorizeRequests()
                .mvcMatchers(HttpMethod.GET, "/api/**").authenticated()
                .anyRequest().authenticated();
    }

 

SecurityConfig 전체 코드

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private AccountService accountService;
    private PasswordEncoder passwordEncoder;

    @Autowired
    public SecurityConfig(AccountService accountService, PasswordEncoder passwordEncoder) {
        this.accountService = accountService;
        this.passwordEncoder = passwordEncoder;
    }

    @Bean
    TokenStore tokenStore() {
        return new InMemoryTokenStore();
    }

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(accountService)
                .passwordEncoder(passwordEncoder);
    }

    /* filter를 적용할지 말지 결정  (Http로 가기전에, WebSecurity를 적용할지 말지)- static resource 허용하기*/
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().mvcMatchers("/docs/index.html");
        web.ignoring().requestMatchers(PathRequest.toStaticResources().atCommonLocations());
    }

    /* filterchain 안에서 거르기*/
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .anonymous()
                .and()
                .formLogin()
                .and()
                .authorizeRequests()
                .mvcMatchers(HttpMethod.GET, "/api/**").authenticated()
                .anyRequest().authenticated();
    }
}

 

application.properties에 시큐리티 로그 설정

logging.level.org.springframework.security=DEBUG