Add argument resolver for SecurityContext

Closes gh-13425
This commit is contained in:
Nermin Karapandzic
2024-01-13 19:33:21 +01:00
committed by Josh Cummings
parent a808c139ad
commit 6e1bcfed11
6 changed files with 269 additions and 23 deletions

View File

@@ -69,9 +69,26 @@ public class CurrentSecurityContextArgumentResolverTests {
SecurityContextHolder.clearContext();
}
@Test
public void supportsParameterNoAnnotationWrongType() {
assertThat(this.resolver.supportsParameter(showSecurityContextNoAnnotationTypeMismatch())).isFalse();
}
@Test
public void supportsParameterNoAnnotation() {
assertThat(this.resolver.supportsParameter(showSecurityContextNoAnnotation())).isFalse();
assertThat(this.resolver.supportsParameter(showSecurityContextNoAnnotation())).isTrue();
}
@Test
public void supportsParameterCustomSecurityContextNoAnnotation() {
assertThat(this.resolver.supportsParameter(showSecurityContextWithCustomSecurityContextNoAnnotation()))
.isTrue();
}
@Test
public void supportsParameterNoAnnotationCustomType() {
assertThat(this.resolver.supportsParameter(showSecurityContextWithCustomSecurityContextNoAnnotation()))
.isTrue();
}
@Test
@@ -88,6 +105,24 @@ public class CurrentSecurityContextArgumentResolverTests {
assertThat(customSecurityContext.getAuthentication().getPrincipal()).isEqualTo(principal);
}
@Test
public void resolveArgumentWithCustomSecurityContextNoAnnotation() {
String principal = "custom_security_context";
setAuthenticationPrincipalWithCustomSecurityContext(principal);
CustomSecurityContext customSecurityContext = (CustomSecurityContext) this.resolver
.resolveArgument(showSecurityContextWithCustomSecurityContextNoAnnotation(), null, null, null);
assertThat(customSecurityContext.getAuthentication().getPrincipal()).isEqualTo(principal);
}
@Test
public void resolveArgumentWithNoAnnotation() {
String principal = "custom_security_context";
setAuthenticationPrincipal(principal);
SecurityContext securityContext = (SecurityContext) this.resolver
.resolveArgument(showSecurityContextNoAnnotation(), null, null, null);
assertThat(securityContext.getAuthentication().getPrincipal()).isEqualTo(principal);
}
@Test
public void resolveArgumentWithCustomSecurityContextTypeMatch() {
String principal = "custom_security_context_type_match";
@@ -212,10 +247,14 @@ public class CurrentSecurityContextArgumentResolverTests {
.resolveArgument(showCurrentSecurityWithErrorOnInvalidTypeMisMatch(), null, null, null));
}
private MethodParameter showSecurityContextNoAnnotation() {
private MethodParameter showSecurityContextNoAnnotationTypeMismatch() {
return getMethodParameter("showSecurityContextNoAnnotation", String.class);
}
private MethodParameter showSecurityContextNoAnnotation() {
return getMethodParameter("showSecurityContextNoAnnotation", SecurityContext.class);
}
private MethodParameter showSecurityContextAnnotation() {
return getMethodParameter("showSecurityContextAnnotation", SecurityContext.class);
}
@@ -276,6 +315,11 @@ public class CurrentSecurityContextArgumentResolverTests {
return getMethodParameter("showCurrentSecurityWithErrorOnInvalidTypeMisMatch", String.class);
}
public MethodParameter showSecurityContextWithCustomSecurityContextNoAnnotation() {
return getMethodParameter("showSecurityContextWithCustomSecurityContextNoAnnotation",
CustomSecurityContext.class);
}
private MethodParameter getMethodParameter(String methodName, Class<?>... paramTypes) {
Method method = ReflectionUtils.findMethod(TestController.class, methodName, paramTypes);
return new MethodParameter(method, 0);
@@ -358,6 +402,12 @@ public class CurrentSecurityContextArgumentResolverTests {
@CurrentSecurityWithErrorOnInvalidType String typeMisMatch) {
}
public void showSecurityContextNoAnnotation(SecurityContext context) {
}
public void showSecurityContextWithCustomSecurityContextNoAnnotation(CustomSecurityContext context) {
}
}
static class CustomSecurityContext implements SecurityContext {

View File

@@ -69,6 +69,14 @@ public class CurrentSecurityContextArgumentResolverTests {
ResolvableMethod securityContextMethod = ResolvableMethod.on(getClass()).named("securityContext").build();
ResolvableMethod securityContextNoAnnotationMethod = ResolvableMethod.on(getClass())
.named("securityContextNoAnnotation")
.build();
ResolvableMethod customSecurityContextNoAnnotationMethod = ResolvableMethod.on(getClass())
.named("customSecurityContextNoAnnotation")
.build();
ResolvableMethod securityContextWithAuthentication = ResolvableMethod.on(getClass())
.named("securityContextWithAuthentication")
.build();
@@ -87,6 +95,19 @@ public class CurrentSecurityContextArgumentResolverTests {
.isTrue();
}
@Test
public void supportsParameterCurrentSecurityContextNoAnnotation() {
assertThat(this.resolver
.supportsParameter(this.securityContextNoAnnotationMethod.arg(Mono.class, SecurityContext.class))).isTrue();
}
@Test
public void supportsParameterCurrentCustomSecurityContextNoAnnotation() {
assertThat(this.resolver.supportsParameter(
this.customSecurityContextNoAnnotationMethod.arg(Mono.class, CustomSecurityContext.class)))
.isTrue();
}
@Test
public void supportsParameterWithAuthentication() {
assertThat(this.resolver
@@ -123,6 +144,40 @@ public class CurrentSecurityContextArgumentResolverTests {
ReactiveSecurityContextHolder.clearContext();
}
@Test
public void resolveArgumentWithSecurityContextNoAnnotation() {
MethodParameter parameter = ResolvableMethod.on(getClass())
.named("securityContextNoAnnotation")
.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.contextWrite(context)
.cast(Mono.class)
.block()
.block();
assertThat(securityContext.getAuthentication()).isSameAs(auth);
ReactiveSecurityContextHolder.clearContext();
}
@Test
public void resolveArgumentWithCustomSecurityContextNoAnnotation() {
MethodParameter parameter = ResolvableMethod.on(getClass())
.named("customSecurityContextNoAnnotation")
.build()
.arg(Mono.class, CustomSecurityContext.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.contextWrite(context)
.cast(Mono.class)
.block()
.block();
assertThat(securityContext.getAuthentication()).isSameAs(auth);
ReactiveSecurityContextHolder.clearContext();
}
@Test
public void resolveArgumentWithCustomSecurityContext() {
MethodParameter parameter = ResolvableMethod.on(getClass())
@@ -350,6 +405,12 @@ public class CurrentSecurityContextArgumentResolverTests {
void securityContext(@CurrentSecurityContext Mono<SecurityContext> monoSecurityContext) {
}
void securityContextNoAnnotation(Mono<SecurityContext> securityContextMono) {
}
void customSecurityContextNoAnnotation(Mono<CustomSecurityContext> securityContextMono) {
}
void customSecurityContext(@CurrentSecurityContext Mono<SecurityContext> monoSecurityContext) {
}