|
@@ -16,9 +16,6 @@
|
|
|
|
|
|
package org.springframework.security.web.reactive.result.method.annotation;
|
|
|
|
|
|
-import static org.assertj.core.api.Assertions.assertThat;
|
|
|
-import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
|
|
-
|
|
|
import java.lang.annotation.ElementType;
|
|
|
import java.lang.annotation.Retention;
|
|
|
import java.lang.annotation.RetentionPolicy;
|
|
@@ -29,6 +26,8 @@ import org.junit.Test;
|
|
|
import org.junit.runner.RunWith;
|
|
|
import org.mockito.Mock;
|
|
|
import org.mockito.junit.MockitoJUnitRunner;
|
|
|
+import reactor.core.publisher.Mono;
|
|
|
+import reactor.util.context.Context;
|
|
|
|
|
|
import org.springframework.core.MethodParameter;
|
|
|
import org.springframework.core.ReactiveAdapterRegistry;
|
|
@@ -43,8 +42,8 @@ import org.springframework.security.web.method.ResolvableMethod;
|
|
|
import org.springframework.web.reactive.BindingContext;
|
|
|
import org.springframework.web.server.ServerWebExchange;
|
|
|
|
|
|
-import reactor.core.publisher.Mono;
|
|
|
-import reactor.util.context.Context;
|
|
|
+import static org.assertj.core.api.Assertions.assertThat;
|
|
|
+import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
|
|
|
|
|
|
|
|
/**
|
|
@@ -71,25 +70,25 @@ public class CurrentSecurityContextArgumentResolverTests {
|
|
|
|
|
|
@Before
|
|
|
public void setup() {
|
|
|
- resolver = new CurrentSecurityContextArgumentResolver(new ReactiveAdapterRegistry());
|
|
|
+ this.resolver = new CurrentSecurityContextArgumentResolver(new ReactiveAdapterRegistry());
|
|
|
this.resolver.setBeanResolver(this.beanResolver);
|
|
|
}
|
|
|
|
|
|
@Test
|
|
|
public void supportsParameterCurrentSecurityContext() {
|
|
|
- assertThat(resolver.supportsParameter(this.securityContextMethod.arg(Mono.class, SecurityContext.class))).isTrue();
|
|
|
+ assertThat(this.resolver.supportsParameter(this.securityContextMethod.arg(Mono.class, SecurityContext.class))).isTrue();
|
|
|
}
|
|
|
|
|
|
@Test
|
|
|
public void supportsParameterWithAuthentication() {
|
|
|
- assertThat(resolver.supportsParameter(this.securityContextWithAuthentication.arg(Mono.class, Authentication.class))).isTrue();
|
|
|
+ assertThat(this.resolver.supportsParameter(this.securityContextWithAuthentication.arg(Mono.class, Authentication.class))).isTrue();
|
|
|
}
|
|
|
|
|
|
@Test
|
|
|
public void resolveArgumentWithNullSecurityContext() {
|
|
|
MethodParameter parameter = ResolvableMethod.on(getClass()).named("securityContext").build().arg(Mono.class, SecurityContext.class);
|
|
|
Context context = ReactiveSecurityContextHolder.withSecurityContext(Mono.empty());
|
|
|
- Mono<Object> argument = resolver.resolveArgument(parameter, bindingContext, exchange);
|
|
|
+ Mono<Object> argument = this.resolver.resolveArgument(parameter, this.bindingContext, this.exchange);
|
|
|
Object obj = argument.subscriberContext(context).block();
|
|
|
assertThat(obj).isNull();
|
|
|
ReactiveSecurityContextHolder.clearContext();
|
|
@@ -100,7 +99,7 @@ public class CurrentSecurityContextArgumentResolverTests {
|
|
|
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 = resolver.resolveArgument(parameter, bindingContext, exchange);
|
|
|
+ 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();
|
|
@@ -111,7 +110,7 @@ public class CurrentSecurityContextArgumentResolverTests {
|
|
|
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 = resolver.resolveArgument(parameter, bindingContext, exchange);
|
|
|
+ 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();
|
|
@@ -122,7 +121,7 @@ public class CurrentSecurityContextArgumentResolverTests {
|
|
|
MethodParameter parameter = ResolvableMethod.on(getClass()).named("securityContext").build().arg(Mono.class, SecurityContext.class);
|
|
|
Authentication auth = null;
|
|
|
Context context = ReactiveSecurityContextHolder.withAuthentication(auth);
|
|
|
- Mono<Object> argument = resolver.resolveArgument(parameter, bindingContext, exchange);
|
|
|
+ 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()).isNull();
|
|
|
ReactiveSecurityContextHolder.clearContext();
|
|
@@ -133,7 +132,7 @@ public class CurrentSecurityContextArgumentResolverTests {
|
|
|
MethodParameter parameter = ResolvableMethod.on(getClass()).named("securityContextWithAuthentication").build().arg(Mono.class, Authentication.class);
|
|
|
Authentication auth = null;
|
|
|
Context context = ReactiveSecurityContextHolder.withAuthentication(auth);
|
|
|
- Mono<Object> argument = resolver.resolveArgument(parameter, bindingContext, exchange);
|
|
|
+ Mono<Object> argument = this.resolver.resolveArgument(parameter, this.bindingContext, this.exchange);
|
|
|
Mono<Object> r = (Mono<Object>) argument.subscriberContext(context).block();
|
|
|
assertThat(r.block()).isNull();
|
|
|
ReactiveSecurityContextHolder.clearContext();
|
|
@@ -144,7 +143,7 @@ public class CurrentSecurityContextArgumentResolverTests {
|
|
|
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 = resolver.resolveArgument(parameter, bindingContext, exchange);
|
|
|
+ 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();
|
|
@@ -155,7 +154,7 @@ public class CurrentSecurityContextArgumentResolverTests {
|
|
|
MethodParameter parameter = ResolvableMethod.on(getClass()).named("securityContextWithDepthPropOptional").build().arg(Mono.class, Object.class);
|
|
|
Authentication auth = null;
|
|
|
Context context = ReactiveSecurityContextHolder.withAuthentication(auth);
|
|
|
- Mono<Object> argument = resolver.resolveArgument(parameter, bindingContext, exchange);
|
|
|
+ Mono<Object> argument = this.resolver.resolveArgument(parameter, this.bindingContext, this.exchange);
|
|
|
Mono<Object> obj = (Mono<Object>) argument.subscriberContext(context).block();
|
|
|
assertThat(obj.block()).isNull();
|
|
|
ReactiveSecurityContextHolder.clearContext();
|
|
@@ -166,7 +165,7 @@ public class CurrentSecurityContextArgumentResolverTests {
|
|
|
MethodParameter parameter = ResolvableMethod.on(getClass()).named("securityContextWithDepthPropOptional").build().arg(Mono.class, Object.class);
|
|
|
Authentication auth = buildAuthenticationWithPrincipal("auth_optional");
|
|
|
Context context = ReactiveSecurityContextHolder.withAuthentication(auth);
|
|
|
- Mono<Object> argument = resolver.resolveArgument(parameter, bindingContext, exchange);
|
|
|
+ Mono<Object> argument = this.resolver.resolveArgument(parameter, this.bindingContext, this.exchange);
|
|
|
Mono<Object> obj = (Mono<Object>) argument.subscriberContext(context).block();
|
|
|
assertThat(obj.block()).isEqualTo("auth_optional");
|
|
|
ReactiveSecurityContextHolder.clearContext();
|
|
@@ -177,7 +176,7 @@ public class CurrentSecurityContextArgumentResolverTests {
|
|
|
MethodParameter parameter = ResolvableMethod.on(getClass()).named("securityContextWithDepthProp").build().arg(Mono.class, Object.class);
|
|
|
Authentication auth = null;
|
|
|
Context context = ReactiveSecurityContextHolder.withAuthentication(auth);
|
|
|
- Mono<Object> argument = resolver.resolveArgument(parameter, bindingContext, exchange);
|
|
|
+ Mono<Object> argument = this.resolver.resolveArgument(parameter, this.bindingContext, this.exchange);
|
|
|
assertThatExceptionOfType(SpelEvaluationException.class).isThrownBy(() -> argument.subscriberContext(context).block());
|
|
|
ReactiveSecurityContextHolder.clearContext();
|
|
|
}
|
|
@@ -187,7 +186,7 @@ public class CurrentSecurityContextArgumentResolverTests {
|
|
|
MethodParameter parameter = ResolvableMethod.on(getClass()).named("securityContextWithDepthStringProp").build().arg(Mono.class, String.class);
|
|
|
Authentication auth = buildAuthenticationWithPrincipal("auth_string");
|
|
|
Context context = ReactiveSecurityContextHolder.withAuthentication(auth);
|
|
|
- Mono<Object> argument = resolver.resolveArgument(parameter, bindingContext, exchange);
|
|
|
+ Mono<Object> argument = this.resolver.resolveArgument(parameter, this.bindingContext, this.exchange);
|
|
|
Mono<String> obj = (Mono<String>) argument.subscriberContext(context).block();
|
|
|
assertThat(obj.block()).isEqualTo("auth_string");
|
|
|
ReactiveSecurityContextHolder.clearContext();
|
|
@@ -198,7 +197,7 @@ public class CurrentSecurityContextArgumentResolverTests {
|
|
|
MethodParameter parameter = ResolvableMethod.on(getClass()).named("errorOnInvalidTypeWhenImplicit").build().arg(Mono.class, String.class);
|
|
|
Authentication auth = buildAuthenticationWithPrincipal("invalid_type_implicit");
|
|
|
Context context = ReactiveSecurityContextHolder.withAuthentication(auth);
|
|
|
- Mono<Object> argument = resolver.resolveArgument(parameter, bindingContext, exchange);
|
|
|
+ Mono<Object> argument = this.resolver.resolveArgument(parameter, this.bindingContext, this.exchange);
|
|
|
Mono<String> obj = (Mono<String>) argument.subscriberContext(context).block();
|
|
|
assertThat(obj.block()).isNull();
|
|
|
ReactiveSecurityContextHolder.clearContext();
|
|
@@ -209,7 +208,7 @@ public class CurrentSecurityContextArgumentResolverTests {
|
|
|
MethodParameter parameter = ResolvableMethod.on(getClass()).named("errorOnInvalidTypeWhenExplicitFalse").build().arg(Mono.class, String.class);
|
|
|
Authentication auth = buildAuthenticationWithPrincipal("error_on_invalid_type_explicit_false");
|
|
|
Context context = ReactiveSecurityContextHolder.withAuthentication(auth);
|
|
|
- Mono<Object> argument = resolver.resolveArgument(parameter, bindingContext, exchange);
|
|
|
+ Mono<Object> argument = this.resolver.resolveArgument(parameter, this.bindingContext, this.exchange);
|
|
|
Mono<String> obj = (Mono<String>) argument.subscriberContext(context).block();
|
|
|
assertThat(obj.block()).isNull();
|
|
|
ReactiveSecurityContextHolder.clearContext();
|
|
@@ -220,7 +219,7 @@ public class CurrentSecurityContextArgumentResolverTests {
|
|
|
MethodParameter parameter = ResolvableMethod.on(getClass()).named("errorOnInvalidTypeWhenExplicitTrue").build().arg(Mono.class, String.class);
|
|
|
Authentication auth = buildAuthenticationWithPrincipal("error_on_invalid_type_explicit_true");
|
|
|
Context context = ReactiveSecurityContextHolder.withAuthentication(auth);
|
|
|
- Mono<Object> argument = resolver.resolveArgument(parameter, bindingContext, exchange);
|
|
|
+ Mono<Object> argument = this.resolver.resolveArgument(parameter, this.bindingContext, this.exchange);
|
|
|
assertThatExceptionOfType(ClassCastException.class).isThrownBy(() -> argument.subscriberContext(context).block());
|
|
|
ReactiveSecurityContextHolder.clearContext();
|
|
|
}
|
|
@@ -230,7 +229,7 @@ public class CurrentSecurityContextArgumentResolverTests {
|
|
|
MethodParameter parameter = ResolvableMethod.on(getClass()).named("currentCustomSecurityContext").build().arg(Mono.class, SecurityContext.class);
|
|
|
Authentication auth = buildAuthenticationWithPrincipal("current_custom_security_context");
|
|
|
Context context = ReactiveSecurityContextHolder.withAuthentication(auth);
|
|
|
- Mono<Object> argument = resolver.resolveArgument(parameter, bindingContext, exchange);
|
|
|
+ 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();
|
|
@@ -241,7 +240,7 @@ public class CurrentSecurityContextArgumentResolverTests {
|
|
|
MethodParameter parameter = ResolvableMethod.on(getClass()).named("currentAuthentication").build().arg(Mono.class, Authentication.class);
|
|
|
Authentication auth = buildAuthenticationWithPrincipal("current_authentication");
|
|
|
Context context = ReactiveSecurityContextHolder.withAuthentication(auth);
|
|
|
- Mono<Object> argument = resolver.resolveArgument(parameter, bindingContext, exchange);
|
|
|
+ Mono<Object> argument = this.resolver.resolveArgument(parameter, this.bindingContext, this.exchange);
|
|
|
Authentication authentication = (Authentication) argument.subscriberContext(context).cast(Mono.class).block().block();
|
|
|
assertThat(authentication).isSameAs(auth);
|
|
|
ReactiveSecurityContextHolder.clearContext();
|
|
@@ -252,7 +251,7 @@ public class CurrentSecurityContextArgumentResolverTests {
|
|
|
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 = resolver.resolveArgument(parameter, bindingContext, exchange);
|
|
|
+ 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();
|
|
@@ -263,7 +262,7 @@ public class CurrentSecurityContextArgumentResolverTests {
|
|
|
MethodParameter parameter = ResolvableMethod.on(getClass()).named("currentSecurityWithErrorOnInvalidTypeMisMatch").build().arg(Mono.class, String.class);
|
|
|
Authentication auth = buildAuthenticationWithPrincipal("current_security_with_error_on_invalid_type_mismatch");
|
|
|
Context context = ReactiveSecurityContextHolder.withAuthentication(auth);
|
|
|
- Mono<Object> argument = resolver.resolveArgument(parameter, bindingContext, exchange);
|
|
|
+ Mono<Object> argument = this.resolver.resolveArgument(parameter, this.bindingContext, this.exchange);
|
|
|
assertThatExceptionOfType(ClassCastException.class).isThrownBy(() -> argument.subscriberContext(context).cast(Mono.class).block().block());
|
|
|
ReactiveSecurityContextHolder.clearContext();
|
|
|
}
|
|
@@ -297,26 +296,28 @@ public class CurrentSecurityContextArgumentResolverTests {
|
|
|
@Target({ ElementType.PARAMETER })
|
|
|
@Retention(RetentionPolicy.RUNTIME)
|
|
|
@CurrentSecurityContext
|
|
|
- static @interface CurrentCustomSecurityContext {
|
|
|
+ @interface CurrentCustomSecurityContext {
|
|
|
}
|
|
|
|
|
|
@Target({ ElementType.PARAMETER })
|
|
|
@Retention(RetentionPolicy.RUNTIME)
|
|
|
@CurrentSecurityContext(expression = "authentication")
|
|
|
- static @interface CurrentAuthentication {
|
|
|
+ @interface CurrentAuthentication {
|
|
|
}
|
|
|
|
|
|
@Target({ ElementType.PARAMETER })
|
|
|
@Retention(RetentionPolicy.RUNTIME)
|
|
|
@CurrentSecurityContext(errorOnInvalidType = true)
|
|
|
- static @interface CurrentSecurityWithErrorOnInvalidType {
|
|
|
+ @interface CurrentSecurityWithErrorOnInvalidType {
|
|
|
}
|
|
|
|
|
|
static class CustomSecurityContext implements SecurityContext {
|
|
|
private Authentication authentication;
|
|
|
+
|
|
|
CustomSecurityContext(Authentication authentication) {
|
|
|
this.authentication = authentication;
|
|
|
}
|
|
|
+
|
|
|
@Override
|
|
|
public Authentication getAuthentication() {
|
|
|
return authentication;
|
|
@@ -327,6 +328,7 @@ public class CurrentSecurityContextArgumentResolverTests {
|
|
|
this.authentication = authentication;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
private Authentication buildAuthenticationWithPrincipal(Object principal) {
|
|
|
return new TestingAuthenticationToken(principal, "password",
|
|
|
"ROLE_USER");
|