Polish CurrentSecurityContextArgumentResolvers

Fixes gh-7487
This commit is contained in:
Josh Cummings 2019-09-27 13:17:37 -06:00
parent 5ef6e7ed6f
commit 5f905232cb
No known key found for this signature in database
GPG Key ID: 49EF60DD7FF83443
5 changed files with 93 additions and 106 deletions

View File

@ -21,7 +21,7 @@ import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.expression.BeanFactoryResolver;
import org.springframework.expression.BeanResolver;
import org.springframework.security.web.bind.support.CurrentSecurityContextArgumentResolver;
import org.springframework.security.web.method.annotation.CurrentSecurityContextArgumentResolver;
import org.springframework.security.web.method.annotation.AuthenticationPrincipalArgumentResolver;
import org.springframework.security.web.method.annotation.CsrfTokenArgumentResolver;
import org.springframework.security.web.servlet.support.csrf.CsrfRequestDataValueProcessor;

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.web.bind.support;
package org.springframework.security.web.method.annotation;
import java.lang.annotation.Annotation;
@ -62,10 +62,10 @@ import org.springframework.web.method.support.ModelAndViewContainer;
* </pre>
*
* <p>
* Will resolve the SecurityContext argument using {@link SecurityContextHolder#getContext()} from
* the {@link SecurityContextHolder}. If the {@link SecurityContext} is null, it will return null.
* If the types do not match, null will be returned unless
* {@link CurrentSecurityContext#errorOnInvalidType()} is true in which case a
* Will resolve the {@link SecurityContext} argument using {@link SecurityContextHolder#getContext()} from
* the {@link SecurityContextHolder}. If the {@link SecurityContext} is {@code null}, it will return {@code null}.
* If the types do not match, {@code null} will be returned unless
* {@link CurrentSecurityContext#errorOnInvalidType()} is {@code true} in which case a
* {@link ClassCastException} will be thrown.
* </p>
*
@ -78,32 +78,19 @@ public final class CurrentSecurityContextArgumentResolver
private ExpressionParser parser = new SpelExpressionParser();
private BeanResolver beanResolver;
/**
* check if this argument resolve can support the parameter.
* @param parameter the method parameter.
* @return true = it can support parameter.
*
* @see
* org.springframework.web.method.support.HandlerMethodArgumentResolver#
* supportsParameter(org.springframework.core.MethodParameter)
* {@inheritDoc}
*/
@Override
public boolean supportsParameter(MethodParameter parameter) {
return findMethodAnnotation(CurrentSecurityContext.class, parameter) != null;
}
/**
* resolve the argument to inject into the controller parameter.
* @param parameter the method parameter.
* @param mavContainer the model and view container.
* @param webRequest the web request.
* @param binderFactory the web data binder factory.
*
* @see org.springframework.web.method.support.HandlerMethodArgumentResolver#
* resolveArgument (org.springframework.core.MethodParameter,
* org.springframework.web.method.support.ModelAndViewContainer,
* org.springframework.web.context.request.NativeWebRequest,
* org.springframework.web.bind.support.WebDataBinderFactory)
* {@inheritDoc}
*/
@Override
public Object resolveArgument(MethodParameter parameter,
ModelAndViewContainer mavContainer, NativeWebRequest webRequest,
WebDataBinderFactory binderFactory) {
@ -138,8 +125,9 @@ public final class CurrentSecurityContextArgumentResolver
}
return securityContextResult;
}
/**
* Sets the {@link BeanResolver} to be used on the expressions
* Set the {@link BeanResolver} to be used on the expressions
* @param beanResolver the {@link BeanResolver} to use
*/
public void setBeanResolver(BeanResolver beanResolver) {
@ -148,7 +136,7 @@ public final class CurrentSecurityContextArgumentResolver
}
/**
* Obtains the specified {@link Annotation} on the specified {@link MethodParameter}.
* Obtain the specified {@link Annotation} on the specified {@link MethodParameter}.
*
* @param annotationClass the class of the {@link Annotation} to find on the
* {@link MethodParameter}

View File

@ -15,7 +15,11 @@
*/
package org.springframework.security.web.reactive.result.method.annotation;
import java.lang.annotation.Annotation;
import org.reactivestreams.Publisher;
import reactor.core.publisher.Mono;
import org.springframework.core.MethodParameter;
import org.springframework.core.ReactiveAdapter;
import org.springframework.core.ReactiveAdapterRegistry;
@ -34,12 +38,10 @@ import org.springframework.util.StringUtils;
import org.springframework.web.reactive.BindingContext;
import org.springframework.web.reactive.result.method.HandlerMethodArgumentResolverSupport;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.lang.annotation.Annotation;
/**
* Resolves the SecurityContext
* Resolves the {@link SecurityContext}
*
* @author Dan Zheng
* @since 5.2
*/
@ -63,13 +65,7 @@ public class CurrentSecurityContextArgumentResolver extends HandlerMethodArgumen
}
/**
* check if this argument resolve can support the parameter.
* @param parameter the method parameter.
* @return true = it can support parameter.
*
* @see
* org.springframework.web.reactive.result.method.HandlerMethodArgumentResolver#
* supportsParameter(org.springframework.core.MethodParameter)
* {@inheritDoc}
*/
@Override
public boolean supportsParameter(MethodParameter parameter) {
@ -77,11 +73,7 @@ public class CurrentSecurityContextArgumentResolver extends HandlerMethodArgumen
}
/**
* resolve the argument to inject into the controller parameter.
* @param parameter the method parameter.
* @param bindingContext the binding context.
* @param exchange the server web exchange.
* @return the reactive mono object result.
* {@inheritDoc}
*/
@Override
public Mono<Object> resolveArgument(MethodParameter parameter, BindingContext bindingContext,

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.web.bind.support;
package org.springframework.security.web.method.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
@ -45,12 +45,11 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
*
*/
public class CurrentSecurityContextArgumentResolverTests {
private Object expectedPrincipal;
private CurrentSecurityContextArgumentResolver resolver;
@Before
public void setup() {
resolver = new CurrentSecurityContextArgumentResolver();
this.resolver = new CurrentSecurityContextArgumentResolver();
}
@After
@ -60,45 +59,48 @@ public class CurrentSecurityContextArgumentResolverTests {
@Test
public void supportsParameterNoAnnotation() {
assertThat(resolver.supportsParameter(showSecurityContextNoAnnotation())).isFalse();
assertThat(this.resolver.supportsParameter(showSecurityContextNoAnnotation())).isFalse();
}
@Test
public void supportsParameterAnnotation() {
assertThat(resolver.supportsParameter(showSecurityContextAnnotation())).isTrue();
assertThat(this.resolver.supportsParameter(showSecurityContextAnnotation())).isTrue();
}
@Test
public void resolveArgumentWithCustomSecurityContext() throws Exception {
public void resolveArgumentWithCustomSecurityContext() {
String principal = "custom_security_context";
setAuthenticationPrincipalWithCustomSecurityContext(principal);
CustomSecurityContext customSecurityContext = (CustomSecurityContext) resolver.resolveArgument(showAnnotationWithCustomSecurityContext(), null, null, null);
CustomSecurityContext customSecurityContext = (CustomSecurityContext)
this.resolver.resolveArgument(showAnnotationWithCustomSecurityContext(), null, null, null);
assertThat(customSecurityContext.getAuthentication().getPrincipal()).isEqualTo(principal);
}
@Test
public void resolveArgumentWithCustomSecurityContextTypeMatch() throws Exception {
public void resolveArgumentWithCustomSecurityContextTypeMatch() {
String principal = "custom_security_context_type_match";
setAuthenticationPrincipalWithCustomSecurityContext(principal);
CustomSecurityContext customSecurityContext = (CustomSecurityContext) resolver.resolveArgument(showAnnotationWithCustomSecurityContext(), null, null, null);
CustomSecurityContext customSecurityContext = (CustomSecurityContext)
this.resolver.resolveArgument(showAnnotationWithCustomSecurityContext(), null, null, null);
assertThat(customSecurityContext.getAuthentication().getPrincipal()).isEqualTo(principal);
}
@Test
public void resolveArgumentNullAuthentication() throws Exception {
public void resolveArgumentNullAuthentication() {
SecurityContext context = SecurityContextHolder.getContext();
Authentication authentication = context.getAuthentication();
context.setAuthentication(null);
assertThat(resolver.resolveArgument(showSecurityContextAuthenticationAnnotation(), null, null, null))
assertThat(this.resolver.resolveArgument(showSecurityContextAuthenticationAnnotation(), null, null, null))
.isNull();
context.setAuthentication(authentication);
}
@Test
public void resolveArgumentWithAuthentication() throws Exception {
public void resolveArgumentWithAuthentication() {
String principal = "john";
setAuthenticationPrincipal(principal);
Authentication auth1 = (Authentication) resolver.resolveArgument(showSecurityContextAuthenticationAnnotation(), null, null, null);
Authentication auth1 = (Authentication)
this.resolver.resolveArgument(showSecurityContextAuthenticationAnnotation(), null, null, null);
assertThat(auth1.getPrincipal()).isEqualTo(principal);
}
@ -109,52 +111,54 @@ public class CurrentSecurityContextArgumentResolverTests {
context.setAuthentication(null);
assertThatExceptionOfType(SpelEvaluationException.class)
.isThrownBy(() -> {
resolver.resolveArgument(showSecurityContextAuthenticationWithPrincipal(), null, null, null);
this.resolver.resolveArgument(showSecurityContextAuthenticationWithPrincipal(), null, null, null);
});
context.setAuthentication(authentication);
}
@Test
public void resolveArgumentWithOptionalPrincipal() throws Exception {
public void resolveArgumentWithOptionalPrincipal() {
SecurityContext context = SecurityContextHolder.getContext();
Authentication authentication = context.getAuthentication();
context.setAuthentication(null);
Object principalResult = resolver.resolveArgument(showSecurityContextAuthenticationWithOptionalPrincipal(), null, null, null);
Object principalResult =
this.resolver.resolveArgument(showSecurityContextAuthenticationWithOptionalPrincipal(), null, null, null);
assertThat(principalResult).isNull();
context.setAuthentication(authentication);
}
@Test
public void resolveArgumentWithPrincipal() throws Exception {
public void resolveArgumentWithPrincipal() {
String principal = "smith";
setAuthenticationPrincipal(principal);
String principalResult = (String) resolver.resolveArgument(showSecurityContextAuthenticationWithPrincipal(), null, null, null);
String principalResult = (String)
this.resolver.resolveArgument(showSecurityContextAuthenticationWithPrincipal(), null, null, null);
assertThat(principalResult).isEqualTo(principal);
}
@Test
public void resolveArgumentUserDetails() throws Exception {
public void resolveArgumentUserDetails() {
setAuthenticationDetail(new User("my_user", "my_password",
AuthorityUtils.createAuthorityList("ROLE_USER")));
User u = (User) resolver.resolveArgument(showSecurityContextWithUserDetail(), null, null,
User u = (User) this.resolver.resolveArgument(showSecurityContextWithUserDetail(), null, null,
null);
assertThat(u.getUsername()).isEqualTo("my_user");
}
@Test
public void resolveArgumentSecurityContextErrorOnInvalidTypeImplicit() throws Exception {
public void resolveArgumentSecurityContextErrorOnInvalidTypeImplicit() {
String principal = "invalid_type_implicit";
setAuthenticationPrincipal(principal);
assertThat(resolver.resolveArgument(showSecurityContextErrorOnInvalidTypeImplicit(), null, null, null))
assertThat(this.resolver.resolveArgument(showSecurityContextErrorOnInvalidTypeImplicit(), null, null, null))
.isNull();
}
@Test
public void resolveArgumentSecurityContextErrorOnInvalidTypeFalse() throws Exception {
public void resolveArgumentSecurityContextErrorOnInvalidTypeFalse() {
String principal = "invalid_type_false";
setAuthenticationPrincipal(principal);
assertThat(resolver.resolveArgument(showSecurityContextErrorOnInvalidTypeFalse(), null, null, null))
assertThat(this.resolver.resolveArgument(showSecurityContextErrorOnInvalidTypeFalse(), null, null, null))
.isNull();
}
@ -162,34 +166,35 @@ public class CurrentSecurityContextArgumentResolverTests {
public void resolveArgumentSecurityContextErrorOnInvalidTypeTrue() {
String principal = "invalid_type_true";
setAuthenticationPrincipal(principal);
assertThatExceptionOfType(ClassCastException.class).isThrownBy(() -> resolver.resolveArgument(showSecurityContextErrorOnInvalidTypeTrue(), null,
null, null));
assertThatExceptionOfType(ClassCastException.class).isThrownBy(() ->
this.resolver.resolveArgument(showSecurityContextErrorOnInvalidTypeTrue(), null, null, null));
}
@Test
public void metaAnnotationWhenCurrentCustomSecurityContextThenInjectSecurityContext() throws Exception {
assertThat(resolver.resolveArgument(showCurrentCustomSecurityContext(), null, null, null))
public void metaAnnotationWhenCurrentCustomSecurityContextThenInjectSecurityContext() {
assertThat(this.resolver.resolveArgument(showCurrentCustomSecurityContext(), null, null, null))
.isNotNull();
}
@Test
public void metaAnnotationWhenCurrentAuthenticationThenInjectAuthentication() throws Exception {
public void metaAnnotationWhenCurrentAuthenticationThenInjectAuthentication() {
String principal = "current_authentcation";
setAuthenticationPrincipal(principal);
Authentication auth1 = (Authentication) resolver.resolveArgument(showCurrentAuthentication(), null, null, null);
Authentication auth1 = (Authentication)
this.resolver.resolveArgument(showCurrentAuthentication(), null, null, null);
assertThat(auth1.getPrincipal()).isEqualTo(principal);
}
@Test
public void metaAnnotationWhenCurrentSecurityWithErrorOnInvalidTypeThenInjectSecurityContext() throws Exception {
assertThat(resolver.resolveArgument(showCurrentSecurityWithErrorOnInvalidType(), null, null, null))
public void metaAnnotationWhenCurrentSecurityWithErrorOnInvalidTypeThenInjectSecurityContext() {
assertThat(this.resolver.resolveArgument(showCurrentSecurityWithErrorOnInvalidType(), null, null, null))
.isNotNull();
}
@Test
public void metaAnnotationWhenCurrentSecurityWithErrorOnInvalidTypeThenMisMatch() {
assertThatExceptionOfType(ClassCastException.class).isThrownBy(() -> resolver.resolveArgument(showCurrentSecurityWithErrorOnInvalidTypeMisMatch(), null,
null, null));
assertThatExceptionOfType(ClassCastException.class).isThrownBy(() ->
this.resolver.resolveArgument(showCurrentSecurityWithErrorOnInvalidTypeMisMatch(), null, null, null));
}
private MethodParameter showSecurityContextNoAnnotation() {
@ -342,13 +347,13 @@ 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 })

View File

@ -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");