토리맘의 한글라이즈 프로젝트 logo 토리맘의 한글라이즈 프로젝트

스프링 시큐리티 공식 레퍼런스를 한글로 번역한 문서입니다.

전체 목차는 여기에 있습니다.

스프링 시큐리티의 메소드 시큐리티 기능에 있는 ReactiveSecurityContextHolder리액터의 컨텍스트를 사용한다. 예를 들어, 아래 예제 코드는 컨텍스트에서 현재 로그인한 사용자의 메세지를 가져오는 방법을 보여준다.

컨텍스트를 사용하려면 메소드는 반드시 MonoFlux같은 org.reactivestreams.Publisher 타입을 반환해야 한다. 리액터의 Context와 통합하려면 필수사항이다.

Authentication authentication = new TestingAuthenticationToken("user", "password", "ROLE_USER");

Mono<String> messageByUsername = ReactiveSecurityContextHolder.getContext()
    .map(SecurityContext::getAuthentication)
    .map(Authentication::getName)
    .flatMap(this::findMessageByUsername)
    // In a WebFlux application the `subscriberContext` is automatically setup using `ReactorContextWebFilter`
    .subscriberContext(ReactiveSecurityContextHolder.withAuthentication(authentication));

StepVerifier.create(messageByUsername)
    .expectNext("Hi user")
    .verifyComplete();

this::findMessageByUsername 정의는 다음과 같다:

Mono<String> findMessageByUsername(String username) {
    return Mono.just("Hi " + username);
}

다음 코드는 리액티브 어플리케이션에서 메소드 시큐리티를 사용하기 위한 최소한의 설정이다:

@EnableReactiveMethodSecurity
public class SecurityConfig {
    @Bean
    public MapReactiveUserDetailsService userDetailsService() {
        User.UserBuilder userBuilder = User.withDefaultPasswordEncoder();
        UserDetails rob = userBuilder.username("rob")
            .password("rob")
            .roles("USER")
            .build();
        UserDetails admin = userBuilder.username("admin")
            .password("admin")
            .roles("USER","ADMIN")
            .build();
        return new MapReactiveUserDetailsService(rob, admin);
    }
}

아래 클래스를 생각해 보자:

@Component
public class HelloWorldMessageService {
    @PreAuthorize("hasRole('ADMIN')")
    public Mono<String> findMessage() {
        return Mono.just("Hello World!");
    }
}

위에 있는 설정을 함께 사용한다면, @PreAuthorize("hasRole('ADMIN')") 덕분에 ADMIN role이 있는 사용자만 findByMessage를 읽을 수 있게 된다. @EnableReactiveMethodSecurity만 추가하면 표준 메소드 시큐리티가 지원하는 모든 표현식을 사용할 수 있다. 단, 현재로서는 Boolean이나 boolean을 반환하는 표현식만 지원한다. 즉, 표현식에 블록을 사용하면 안 된다.

웹플럭스 시큐리티와 통합하면, 스프링 시큐리티가 자동으로 인증된 사용자에 따라 리액터 컨텍스트를 설정한다.

@EnableWebFluxSecurity
@EnableReactiveMethodSecurity
public class SecurityConfig {

    @Bean
    SecurityWebFilterChain springWebFilterChain(ServerHttpSecurity http) throws Exception {
        return http
            // Demonstrate that method security works
            // Best practice to use both for defense in depth
            .authorizeExchange(exchanges -> exchanges
                .anyExchange().permitAll()
            )
            .httpBasic(withDefaults())
            .build();
    }

    @Bean
    MapReactiveUserDetailsService userDetailsService() {
        User.UserBuilder userBuilder = User.withDefaultPasswordEncoder();
        UserDetails rob = userBuilder.username("rob")
            .password("rob")
            .roles("USER")
            .build();
        UserDetails admin = userBuilder.username("admin")
            .password("admin")
            .roles("USER","ADMIN")
            .build();
        return new MapReactiveUserDetailsService(rob, admin);
    }
}

전체 샘플 코드는 hellowebflux-method에서 확인할 수 있다.


Next :
Reactive Test Support
리액티브 환경에서 지원하는 스프링 시큐리티 테스트 기능을 설명합니다. 공식 문서에 있는 "Reactive Test Support" 챕터를 한글로 번역한 문서입니다.

전체 목차는 여기에 있습니다.

<< >>

TOP