Search in sources :

Example 66 with Mono

use of reactor.core.publisher.Mono in project spring-security by spring-projects.

the class CurrentSecurityContextArgumentResolverTests method resolveArgumentWithCustomSecurityContext.

@Test
public void resolveArgumentWithCustomSecurityContext() {
    MethodParameter parameter = ResolvableMethod.on(getClass()).named("customSecurityContext").build().arg(Mono.class, SecurityContext.class);
    Authentication auth = buildAuthenticationWithPrincipal("hello");
    Context context = ReactiveSecurityContextHolder.withSecurityContext(Mono.just(new CustomSecurityContext(auth)));
    Mono<Object> argument = this.resolver.resolveArgument(parameter, this.bindingContext, this.exchange);
    CustomSecurityContext securityContext = (CustomSecurityContext) argument.subscriberContext(context).cast(Mono.class).block().block();
    assertThat(securityContext.getAuthentication()).isSameAs(auth);
    ReactiveSecurityContextHolder.clearContext();
}
Also used : BindingContext(org.springframework.web.reactive.BindingContext) CurrentSecurityContext(org.springframework.security.core.annotation.CurrentSecurityContext) Context(reactor.util.context.Context) SecurityContext(org.springframework.security.core.context.SecurityContext) Authentication(org.springframework.security.core.Authentication) Mono(reactor.core.publisher.Mono) MethodParameter(org.springframework.core.MethodParameter) Test(org.junit.jupiter.api.Test)

Example 67 with Mono

use of reactor.core.publisher.Mono in project spring-security by spring-projects.

the class CurrentSecurityContextArgumentResolverTests method resolveArgumentWithAuthentication1.

@Test
public void resolveArgumentWithAuthentication1() {
    MethodParameter parameter = ResolvableMethod.on(getClass()).named("securityContextWithAuthentication").build().arg(Mono.class, Authentication.class);
    Authentication auth = buildAuthenticationWithPrincipal("authentication1");
    Context context = ReactiveSecurityContextHolder.withAuthentication(auth);
    Mono<Object> argument = this.resolver.resolveArgument(parameter, this.bindingContext, this.exchange);
    Mono<Authentication> auth1 = (Mono<Authentication>) argument.subscriberContext(context).block();
    assertThat(auth1.block()).isSameAs(auth);
    ReactiveSecurityContextHolder.clearContext();
}
Also used : BindingContext(org.springframework.web.reactive.BindingContext) CurrentSecurityContext(org.springframework.security.core.annotation.CurrentSecurityContext) Context(reactor.util.context.Context) SecurityContext(org.springframework.security.core.context.SecurityContext) Authentication(org.springframework.security.core.Authentication) Mono(reactor.core.publisher.Mono) MethodParameter(org.springframework.core.MethodParameter) Test(org.junit.jupiter.api.Test)

Example 68 with Mono

use of reactor.core.publisher.Mono in project spring-security by spring-projects.

the class CurrentSecurityContextArgumentResolverTests method resolveArgumentWithSecurityContext.

@Test
public void resolveArgumentWithSecurityContext() {
    MethodParameter parameter = ResolvableMethod.on(getClass()).named("securityContext").build().arg(Mono.class, SecurityContext.class);
    Authentication auth = buildAuthenticationWithPrincipal("hello");
    Context context = ReactiveSecurityContextHolder.withAuthentication(auth);
    Mono<Object> argument = this.resolver.resolveArgument(parameter, this.bindingContext, this.exchange);
    SecurityContext securityContext = (SecurityContext) argument.subscriberContext(context).cast(Mono.class).block().block();
    assertThat(securityContext.getAuthentication()).isSameAs(auth);
    ReactiveSecurityContextHolder.clearContext();
}
Also used : BindingContext(org.springframework.web.reactive.BindingContext) CurrentSecurityContext(org.springframework.security.core.annotation.CurrentSecurityContext) Context(reactor.util.context.Context) SecurityContext(org.springframework.security.core.context.SecurityContext) Authentication(org.springframework.security.core.Authentication) Mono(reactor.core.publisher.Mono) CurrentSecurityContext(org.springframework.security.core.annotation.CurrentSecurityContext) SecurityContext(org.springframework.security.core.context.SecurityContext) MethodParameter(org.springframework.core.MethodParameter) Test(org.junit.jupiter.api.Test)

Example 69 with Mono

use of reactor.core.publisher.Mono in project spring-security by spring-projects.

the class CurrentSecurityContextArgumentResolverTests method metaAnnotationWhenCurrentSecurityWithErrorOnInvalidTypeThenInjectSecurityContext.

@Test
public void metaAnnotationWhenCurrentSecurityWithErrorOnInvalidTypeThenInjectSecurityContext() {
    MethodParameter parameter = ResolvableMethod.on(getClass()).named("currentSecurityWithErrorOnInvalidType").build().arg(Mono.class, SecurityContext.class);
    Authentication auth = buildAuthenticationWithPrincipal("current_security_with_error_on_invalid_type");
    Context context = ReactiveSecurityContextHolder.withAuthentication(auth);
    Mono<Object> argument = this.resolver.resolveArgument(parameter, this.bindingContext, this.exchange);
    SecurityContext securityContext = (SecurityContext) argument.subscriberContext(context).cast(Mono.class).block().block();
    assertThat(securityContext.getAuthentication()).isSameAs(auth);
    ReactiveSecurityContextHolder.clearContext();
}
Also used : BindingContext(org.springframework.web.reactive.BindingContext) CurrentSecurityContext(org.springframework.security.core.annotation.CurrentSecurityContext) Context(reactor.util.context.Context) SecurityContext(org.springframework.security.core.context.SecurityContext) Authentication(org.springframework.security.core.Authentication) Mono(reactor.core.publisher.Mono) CurrentSecurityContext(org.springframework.security.core.annotation.CurrentSecurityContext) SecurityContext(org.springframework.security.core.context.SecurityContext) MethodParameter(org.springframework.core.MethodParameter) Test(org.junit.jupiter.api.Test)

Example 70 with Mono

use of reactor.core.publisher.Mono in project spring-security by spring-projects.

the class PrePostAdviceReactiveMethodInterceptor method invoke.

@Override
public Object invoke(final MethodInvocation invocation) {
    Method method = invocation.getMethod();
    Class<?> returnType = method.getReturnType();
    boolean isSuspendingFunction = KotlinDetector.isSuspendingFunction(method);
    boolean hasFlowReturnType = COROUTINES_FLOW_CLASS_NAME.equals(new MethodParameter(method, RETURN_TYPE_METHOD_PARAMETER_INDEX).getParameterType().getName());
    boolean hasReactiveReturnType = Publisher.class.isAssignableFrom(returnType) || isSuspendingFunction || hasFlowReturnType;
    Assert.state(hasReactiveReturnType, () -> "The returnType " + returnType + " on " + method + " must return an instance of org.reactivestreams.Publisher " + "(i.e. Mono / Flux) or the function must be a Kotlin coroutine " + "function in order to support Reactor Context");
    Class<?> targetClass = invocation.getThis().getClass();
    Collection<ConfigAttribute> attributes = this.attributeSource.getAttributes(method, targetClass);
    PreInvocationAttribute preAttr = findPreInvocationAttribute(attributes);
    // @formatter:off
    Mono<Authentication> toInvoke = ReactiveSecurityContextHolder.getContext().map(SecurityContext::getAuthentication).defaultIfEmpty(this.anonymous).filter((auth) -> this.preInvocationAdvice.before(auth, invocation, preAttr)).switchIfEmpty(Mono.defer(() -> Mono.error(new AccessDeniedException("Denied"))));
    // @formatter:on
    PostInvocationAttribute attr = findPostInvocationAttribute(attributes);
    if (Mono.class.isAssignableFrom(returnType)) {
        return toInvoke.flatMap((auth) -> PrePostAdviceReactiveMethodInterceptor.<Mono<?>>proceed(invocation).map((r) -> (attr != null) ? this.postAdvice.after(auth, invocation, attr, r) : r));
    }
    if (Flux.class.isAssignableFrom(returnType)) {
        return toInvoke.flatMapMany((auth) -> PrePostAdviceReactiveMethodInterceptor.<Flux<?>>proceed(invocation).map((r) -> (attr != null) ? this.postAdvice.after(auth, invocation, attr, r) : r));
    }
    if (hasFlowReturnType) {
        Flux<?> response;
        if (isSuspendingFunction) {
            response = toInvoke.flatMapMany((auth) -> Flux.from(CoroutinesUtils.invokeSuspendingFunction(invocation.getMethod(), invocation.getThis(), invocation.getArguments())).map((r) -> (attr != null) ? this.postAdvice.after(auth, invocation, attr, r) : r));
        } else {
            ReactiveAdapter adapter = ReactiveAdapterRegistry.getSharedInstance().getAdapter(returnType);
            Assert.state(adapter != null, () -> "The returnType " + returnType + " on " + method + " must have a org.springframework.core.ReactiveAdapter registered");
            response = toInvoke.flatMapMany((auth) -> Flux.from(adapter.toPublisher(PrePostAdviceReactiveMethodInterceptor.flowProceed(invocation))).map((r) -> (attr != null) ? this.postAdvice.after(auth, invocation, attr, r) : r));
        }
        return KotlinDelegate.asFlow(response);
    }
    if (isSuspendingFunction) {
        Mono<?> response = toInvoke.flatMap((auth) -> Mono.from(CoroutinesUtils.invokeSuspendingFunction(invocation.getMethod(), invocation.getThis(), invocation.getArguments())).map((r) -> (attr != null) ? this.postAdvice.after(auth, invocation, attr, r) : r));
        return KotlinDelegate.awaitSingleOrNull(response, invocation.getArguments()[invocation.getArguments().length - 1]);
    }
    return toInvoke.flatMapMany((auth) -> Flux.from(PrePostAdviceReactiveMethodInterceptor.<Publisher<?>>proceed(invocation)).map((r) -> (attr != null) ? this.postAdvice.after(auth, invocation, attr, r) : r));
}
Also used : Continuation(kotlin.coroutines.Continuation) AwaitKt(kotlinx.coroutines.reactive.AwaitKt) MethodSecurityMetadataSource(org.springframework.security.access.method.MethodSecurityMetadataSource) KotlinDetector(org.springframework.core.KotlinDetector) MethodInvocation(org.aopalliance.intercept.MethodInvocation) ReactiveSecurityContextHolder(org.springframework.security.core.context.ReactiveSecurityContextHolder) MethodParameter(org.springframework.core.MethodParameter) Method(java.lang.reflect.Method) ReactiveAdapterRegistry(org.springframework.core.ReactiveAdapterRegistry) ConfigAttribute(org.springframework.security.access.ConfigAttribute) ReactiveFlowKt(kotlinx.coroutines.reactive.ReactiveFlowKt) CoroutinesUtils(org.springframework.core.CoroutinesUtils) ReactiveAdapter(org.springframework.core.ReactiveAdapter) Collection(java.util.Collection) Publisher(org.reactivestreams.Publisher) Mono(reactor.core.publisher.Mono) AccessDeniedException(org.springframework.security.access.AccessDeniedException) MethodInterceptor(org.aopalliance.intercept.MethodInterceptor) Flux(reactor.core.publisher.Flux) SecurityContext(org.springframework.security.core.context.SecurityContext) AnonymousAuthenticationToken(org.springframework.security.authentication.AnonymousAuthenticationToken) Exceptions(reactor.core.Exceptions) Authentication(org.springframework.security.core.Authentication) AuthorityUtils(org.springframework.security.core.authority.AuthorityUtils) Assert(org.springframework.util.Assert) AccessDeniedException(org.springframework.security.access.AccessDeniedException) ConfigAttribute(org.springframework.security.access.ConfigAttribute) Mono(reactor.core.publisher.Mono) Flux(reactor.core.publisher.Flux) Method(java.lang.reflect.Method) Authentication(org.springframework.security.core.Authentication) MethodParameter(org.springframework.core.MethodParameter) ReactiveAdapter(org.springframework.core.ReactiveAdapter)

Aggregations

Mono (reactor.core.publisher.Mono)308 Test (org.junit.jupiter.api.Test)143 StepVerifier (reactor.test.StepVerifier)117 List (java.util.List)116 Flux (reactor.core.publisher.Flux)110 Assertions.assertThat (org.assertj.core.api.Assertions.assertThat)102 Collections (java.util.Collections)85 Map (java.util.Map)75 HttpStatus (org.springframework.http.HttpStatus)66 ServerWebExchange (org.springframework.web.server.ServerWebExchange)65 Duration (java.time.Duration)60 ArrayList (java.util.ArrayList)58 Test (org.junit.Test)53 MockServerHttpRequest (org.springframework.web.testfixture.http.server.reactive.MockServerHttpRequest)52 DataBuffer (org.springframework.core.io.buffer.DataBuffer)51 Assert (org.springframework.util.Assert)49 Mockito.mock (org.mockito.Mockito.mock)48 MockServerWebExchange (org.springframework.web.testfixture.server.MockServerWebExchange)46 Optional (java.util.Optional)44 StandardCharsets (java.nio.charset.StandardCharsets)43