[SpringBoot] Spring Security #1 MVC, WebFlux Security

2022. 11. 20. 15:44JAVA/Spring

Spring Security

만약 Spring Security가 classpath에 있다면, 웹 애플리케이션들은 기본적으로 보호됩니다. Spring Boot는 Spring Security의 content-negotiation strategy에 의존하여 httpBasic을 사용할지 아니면 formLogin을 사용할지 결정합니다.

  • content-negotiation stragegy : user agent(사용자를 대표하는 컴퓨터 프로그램, 웹 맥락에선 브라우저를 의미함)가 어떤 URI에 있는 리소스를 요청할때, 해당 리소스가 사용자에게 적절한 형태(예를 들어 컨텐츠를 한글로 보여줄지, 영어로 보여줄지)로 받도록 정하게 해주는 방법
  • httpBasic : Http Basic 인증, Http 프로토콜에서 정의한 기본 인증
  • formLogin : Srping Security에서 제공하는 인증 방식

 

애플리케이션에 메서드 레벨 보안(security)을 추가하기 위해서 @EnableGlobalMethodSecurity 애노테이션을 추가할 수 있습니다. 추가적인 정보는 다음과 같습니다.

https://docs.spring.io/spring-security/reference/5.7.2/servlet/authorization/method-security.html

 

Method Security :: Spring Security

Sometimes you may need to perform operations that are more complicated than are possible with the @EnableGlobalMethodSecurity annotation allow. For these instances, you can extend the GlobalMethodSecurityConfiguration ensuring that the @EnableGlobalMethodS

docs.spring.io

 

기본적인 UserDetailService는 단일 사용자가 있습니다. 사용자 이름은 user, 비밀번호는 임의이고 애플리케이션 시작할때 WRAN 레벨에서 출력됩니다. 다음 예제와 같이 출력됩니다.

Using generated security password: 78fa095d-3f4c-48b1-ad50-e24c31d5cf35

This generated password is for development use only. Your security configuration must be updated before running your application in production.

 

spring.security.user.name 프로퍼티와 spring.security.user.password 프로퍼티를 이용하여 username과 password를 변경할 수 있습니다.

 

웹 애플리케이션이 사용하는 기본 기능

  • 매노리 내 저장소(in-memory store)와 단일 사용자(생성한 암호 소유)를 가진 UserDetailService 기능
    • WebFlux 애플리케이션의 경우 ReactiveUserDetailService 기능을 가짐
  • 전체적인 애플리케이션에 대한 폼 기반 로그인(Form-based Login)이나 HTTP 기본 보안(HTTP Basic Security, 요청의 헤더에 Accept에 따른) 기능(만약 actuator가 클래스패스에 있다면 actuator endpoints가 포함된다.)
    • Actuator : 운영중인 애플리케이션을 HTTP나 JMX을 이용해서 모니터링하고 관리할 수 있는 기능
    • endpoints : 모니터링이나 조작을 할 수 있도록 하는 연결점, 기본 endpoints를 제공하고 사용자가 필요에 따라 추가할 수 있음
  • 애플리케이션 이벤트들을 배급(publishing)하는 DefaultAutenticationEventPublisher 기능
    • DefaultAutenticationEventPublisher : 인증 성공 또는 실패와 같은 이벤트 발생시 동작을 정의하는데 사용됨
    • 빈을 추가함으로써 다른 AutenticationEventPubsliher를 제공할 수 있음

 

1. MVC Security

기본적인 보안 설정은 SecurityAutoConfiguration 클래스와 UserDetailServiceAutoConfiguration 클래스에 구현되어있습니다. SecurityAutoConfiguration은 웹 보안에 대한 SpringBootWebSecurityConfiguration을 임포트합니다. UserDetailServiceAutoConfiguration은 인증을 설정합니다. 이는 웹이 아닌 애플리케이션과도 관련이 있습니다. 기본적인 웹 애플리케이션 보안 설정을 완전히 해제하거나 OAuth2와 Resource Server와 같은 여러개의 Spring Security 컴포넌트들로 결합하기 위해서는 SecurityFilterChain 타입의 빈(이렇게 해도 UserDetailService 설정이나 Actuator의 보안이 비활성화 되지 않습니다.)을 추가하시오. 

 

UserDetailService 설정을 해제하기 위해서 UserDetailService, AuthenticationProvider 또는 AutenticationManager 타입의 빈을 추가하세요.

 

커스텀한 SecurityFilterChain이나 WebSecurityConfigurerAdapter 빈을 추가함으로써 접근 규칙(Access Rule)들을 재정할 수 있습니다. SpringBoot는 actuator endpoints와 정적 리소스들에 대한 접근 규칙을 재정의 할 수 있는 메서드를 제공합니다. EndpointRequest는 management.endpoints.web.base-path 프로퍼티를 기반으로한 RequestMatcher 생성하는데 사용될 수 있습니다. PathRequest를 사용하여 일반적으로 사용되는 위치의 리소스에 대한 RequestMatcher를 생성할 수 있습니다.

 

2. WebFlux Security

Spring MVC 애플리케이션들과 비슷하게 spring-boot-starter-security 의존성을 추가함으로써 WebFlux 애플리케이션들을 보호할 수 있습니다. 기본적인 보안 설정은 ReactiveSecurityAutoConfigurationUserDetailServiceAutoConfiguration을 사용합니다. ReactiveSecurityAutoConfiguration은 WebFluxSecurityConfiguration을 웹 보안에 대해서 임포트하고 UserDetailServiceAutoConfiguration은 인증을 설정합니다. 이는 웹이 아닌 애플리케이션과도 관련이 있습니다. 기본적인 웹 애플리케이션 보안 설정을 완전하게 해제하기 위해서 WebFilterChainProxy 타입의 빈을 추가할 수 있습니다.(이렇게 해도 UserDetailService 설정이나 Actuator의 보안이 비활성화 되지 않습니다.)

 

UserDetailService 설정을 해제하기 위해서는 ReactiveUserDetailServiceReactiveAutenticationManager 타입의 빈을 추가할 수 있습니다.

 

접근 규칙(Access Rule), OAuth 2 클라이언트와 같은 여러개의 Spring Security 컴포넌트의 사용, Resource Server는 커스텀한 SecurityWebFilterChain 빈을 추가함으로써 설정할 수 있습니다. SpringBoot는 actuator endpoints와 정적 리소스에 대한 접근 규칙을 재정의하는 메서드를 제공합니다. EndpointRequest는 management.endpoints.web.base-path 프로퍼티를 기반으로한 ServerWebExchangeMatcher를 생성할 수 있습니다.

 

PathRequest는 일반적으로 사용되는 위치의 리소스에 대한 ServerWebExchangeMatcher를 생성할 수 있습니다.

 

예를 들어 보안 설정을 다음과 같이 설정할 수 있습니다.

@Configuration(proxyBeanMethods = false) // 빈 메서드 호출마다 새로운 객체 생성
@EnableWebFluxSecurity
public class MyWebFluxSecurityConfiguration {
    @Bean
    public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http){
        http.authorizeExchange((exchange) -> {
            exchange.matchers(PathRequest.toStaticResources().atCommonLocations()).permitAll();
            exchange.pathMatchers("/foo", "/bar").authenticated();
        });
        http.formLogin(withDefaults());
        return http.build();
    }
}

 

 

References

https://docs.spring.io/spring-boot/docs/2.7.2/reference/htmlsingle/#web.security
[spring] spring boot에서 actuator 사용하기
[http] Content Negotiation 콘텐츠 협상