[Spring Security] Authentication and Authorization

Juhye Pyoun·2023년 9월 19일
0

Spring

목록 보기
7/7

Spring Security란?

Spring 기반의 애플리케이션의 보안(인증과 권한, 인가 등)을 담당하는 스프링 하위 프레임워크

Spring framework에서는 인증 및 권한 부여로 리소스 사용을 컨트롤 할 수 있는 Spring Security를 제공한다.
Spring Security는 보안과 관련해서 체계적으로 많은 옵션을 제공해주기 때문에 개발자 입장에서는 일일이 보안관련 로직을 작성하지 않아도 된다는 장점이 있다.

인증(Authorizatoin)과 인가(Authentication)

  • 인증(Authentication) : 해당 사용자가 본인이 맞는지 확인하는 과정

  • 인가(Authorization) : 해당 사용자가 요청하는 자원을 실행할 수 있는 권한이 있는가를 확인하는 과정

Spring Security는 기본적으로 인증 절차를 거친 후에 인가 절차를 진행하며, 인가 과정에서 해당 리소스에 접근 권한이 있는지 확인하게 된다.

Spring Security에서는 이러한 인증과 인가를 위해 Principal을 아이디로, Credential을 비밀번호로 사용하는 Credential 기반의 인증 방식을 사용한다.

  • Principal(접근 주체) : 보호받는 Resource에 접근하는 대상
  • Credential(비밀번호) : Resource에 접근하는 대상의 비밀번호

 

Spring Security Filter

Spring Security는 '인증'과 '권한'에 대한 부분을 Filter 흐름에 따라 처리하고 있다.
Spring Security는 스프링의 DispatcherServlet 앞단에 Filter 형태로 위치한다. Dispatcher로 넘어가기 전에 이 Filter가 요청을 가로채서, 클라이언트의 리소스 접근 권한을 확인하고, 없는 경우에는 인증 요청 화면으로 자동 리다이렉트한다.

Spring Security는 다양한 기능을 가진 필터들을 10개 이상 기본적으로 제공한다. 이렇게 제공되는 필터들을 Security Filter Chain(시큐리티 필터 체인)이라고 한다.

 

종류가 매우 많지만 여기서 중요한 것은 필터의 처리순서다.

클라이언트가 리소스에 대한 접근 권한이 없는 경우 기본적으로 로그인 폼으로 보내게 되는데 그 역할을 하는 필터는
UsernamePasswordAuthenticationFilter 이다.

Rest Api에서는 로그인 폼이 따로 없기 때문에 인증 권한이 없다는 오류를 JSON으로 내려줘야 하므로 UsernamePasswordAuthenticationFilter 전에 관련 처리를 넣어줘야 한다.

 

JWT를 통한 API 인증 및 권한 부여 순서

  1. 인증을 위해 회원 가입, 로그인 API를 구현한다.
  2. 리소스에 접근 가능한 ROLE_USER 권한을 가입 회원에게 부여한다.
  3. Spring Security 설정에서 ROLE_USER 권한을 가지면 접근 가능하도록 세팅한다.
  4. 권한이 있는 회원이 로그인에 성공하면 리소스에 접근 가능한 JWT 토큰을 발급한다.
  5. 해당 회원은 권한이 필요한 API 접근 시 JWT 보안 토큰을 사용한다.

👉 접근 제한이 필요한 API에는 보안 토큰을 통해서 이 유저가 권한이 있는지 여부를 Spring Security를 통해 체크하고 리소스를 요청할 수 있도록 구성할 수 있다.

 

Spring Security Configuration

서버에 보안을 설정하기 위해 Configuration을 만든다.
USER에 대한 권한을 설정하기 위한 작업도 여기서 진행된다.

@Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .httpBasic().disable() // rest api 이므로 기본설정 사용안함. 기본설정은 비인증시 로그인폼 화면으로 리다이렉트
                .cors().configurationSource(corsConfigurationSource())
                .and()
                .csrf().disable() // rest api이므로 csrf 보안이 필요없으므로 disable처리.
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) // jwt token으로 인증하므로 세션은 필요없으므로 생성안함.
                .and()
                .authorizeRequests() // 다음 리퀘스트에 대한 사용권한 체크
                .antMatchers("/*/signin", "/*/signin/**", "/*/signup", "/*/signup/**", "/social/**").permitAll() // 가입 및 인증 주소는 누구나 접근가능
                .antMatchers(HttpMethod.GET, "home/**").permitAll() // home으로 시작하는 GET요청 리소스는 누구나 접근가능
                .anyRequest().hasRole("USER") // 그외 나머지 요청은 모두 인증된 회원만 접근 가능
                .and()
                .addFilterBefore(new JwtAuthenticationFilter(jwtTokenProvider), UsernamePasswordAuthenticationFilter.class); // jwt token 필터를 id/password 인증 필터 전에 넣는다

    }

 

[참고자료]

링크1🔗
링크2🔗
링크3🔗
링크4🔗

0개의 댓글

관련 채용 정보