SpringBoot SpringSecurity 설정 1-1. @EnableWebSecurity 설정

jeonbang123·2023년 3월 30일
0

springboot

목록 보기
6/14

1. depency 추가

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

2. Controller 추가

package com.codesign.base.security.controller;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequiredArgsConstructor
@Slf4j
@RequestMapping("/api/v1/test")
public class TestController {

    @RequestMapping("/permit-all")
    public Object test1(){
        return ResponseEntity.ok("permit-all");
    }


    @RequestMapping("/auth")
    public Object test2(){
        return ResponseEntity.ok("auth");
    }
}

3. SecurityConfig 추가

package com.codesign.base.configure;

import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
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;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .cors().and()
                .csrf().disable()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
                .authorizeRequests()
                .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
                .antMatchers("/api/v1/test/permit-all").permitAll()
                .antMatchers("/api/v1/test/auth").authenticated()
                .antMatchers("/**").authenticated()
                .anyRequest().permitAll().and()
                .formLogin().disable()
        ;
    }
}
Annotation
설명
@EnableWebSecurity이 주석을 @Configuration 클래스에 추가하여 WebSecurityConfigurer에 정의된 SpringSecurity 구성을 지정하거나 SecurityFilterChain을 노출하여 다음과 같이 설정할 수 있습니다:
@Configuration클래스가 하나 이상의 @Bean 메서드를 선언하고 Spring 컨테이너에 의해 처리되어 런타임에 해당 Bean에 대한 Bean 정의 및 서비스 요청을 생성할 수 있음을 나타냅니다

속성
설명
cors()corsFilter 활성
csrf().disable()Rest API 서버일경우, 세션기반 인증이 아닌 토큰방식의 Stateless방식을 사용하기 때문에 csrf를 사용할 필요가 없다.
sessionManagement()
.sessionCreationPolicy(
SessionCreationPolicy.STATELESS)
현재 스프링 시큐리티에서 세션을 관리하지 않겠다는 뜻입니다. 서버에서 관리되는 세션 없이 클라이언트에서 요청하는 헤더에 token을 담아보낸다면 서버에서 토큰을 확인하여 인증하는 방식을 사용할 것이므로 서버에서 관리되어야할 세션이 필요없어지게 됩니다.
Rest API 서버의경우, 세션기반 인증이 아닌 토큰 방식의 Stateless방식을 사용한다.
authorizeRequests()이제부터 인증절차에 대한 설정을 진행하겠다는 것입니다.
antMatchers()특정 URL 에 대해서 어떻게 인증처리를 할지 결정합니다.
HttpMethod.OPTIONS브라우저에서 서버로 요청을 보낼때, 메서드와 헤더를 허용하는지 미리 확인하는 통신 확인 요청이다.
permitAll()스프링 시큐리티에서 인증이 되지 않더라도 통과시켜 누구에게나 사용을 열어줍니다.
authenticated()요청내에 스프링 시큐리티 컨텍스트 내에서 인증이 완료되어야 api를 사용할 수 있습니다. 인증이 되지 않은 요청은 403(Forbidden)이 내려집니다.
anyRequest()모든 요청을 의미한다.
.antMatchers("/**").authenticated().anyRequest().permitAll()
>>> anyRequest().authenticated() 이걸로 변경해도 될거 같다.
formLogin().disable()formLogin 미사용

CSRF

Cross site Request forgery로 사이즈간 위조 요청인데, 즉 정상적인 사용자가 의도치 않은 위조요청을 보내는 것을 의미한다.
예를 들어 A라는 도메인에서, 인증된 사용자 H가 위조된 request를 포함한 link, email을 사용하였을 경우(클릭, 또는 사이트 방문만으로도), A 도메인에서는 이 사용자가 일반 유저인지, 악용된 공격인지 구분할 수가 없다.
CSRF protection은 spring security에서 default로 설정된다. 즉, protection을 통해 GET요청을 제외한 상태를 변화시킬 수 있는 POST, PUT, DELETE 요청으로부터 보호한다.
csrf protection을 적용하였을 때, html에서 다음과 같은 csrf 토큰이 포함되어야 요청을 받아들이게 됨으로써, 위조 요청을 방지하게 됩니다.

Rest api에서의 CSRF

그래서 이렇게 보안 수준을 향상시키는 CSRF를 왜 disable 하였을까? spring security documentation에 non-browser clients 만을 위한 서비스라면 csrf를 disable 하여도 좋다고 한다.
이 이유는 rest api를 이용한 서버라면, session 기반 인증과는 다르게 stateless하기 때문에 서버에 인증정보를 보관하지 않는다. rest api에서 client는 권한이 필요한 요청을 하기 위해서는 요청에 필요한 인증 정보를(OAuth2, jwt토큰 등)을 포함시켜야 한다. 따라서 서버에 인증정보를 저장하지 않기 때문에 굳이 불필요한 csrf 코드들을 작성할 필요가 없다.

참조 https://velog.io/@woohobi/Spring-security-csrf%EB%9E%80

4. 테스트

- api/v1/test/auth


.antMatchers("/api/v1/test/auth").authenticated() 인증되지 않아 403(Forbidden) Error, Access Denied 된거 확인

- api/v1/test/permit-all

.antMatchers("/api/v1/test/permit-all").permitAll() 인증 상관없이 통과 확인

참조
https://sas-study.tistory.com/357
https://velog.io/@woohobi/Spring-security-csrf%EB%9E%80

profile
Design Awesome Style Code

0개의 댓글