Skip to content

Commit 64e063d

Browse files
Dav1ddeeleftherias
authored andcommitted
switches web authentication principal resolver to use reactive context
gh #6598 Signed-off-by: David Herberth <[email protected]>
1 parent 8e53c3f commit 64e063d

File tree

2 files changed

+24
-34
lines changed

2 files changed

+24
-34
lines changed

web/src/main/java/org/springframework/security/web/reactive/result/method/annotation/AuthenticationPrincipalArgumentResolver.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,9 @@
2828
import org.springframework.expression.ExpressionParser;
2929
import org.springframework.expression.spel.standard.SpelExpressionParser;
3030
import org.springframework.expression.spel.support.StandardEvaluationContext;
31-
import org.springframework.security.core.Authentication;
3231
import org.springframework.security.core.annotation.AuthenticationPrincipal;
32+
import org.springframework.security.core.context.ReactiveSecurityContextHolder;
33+
import org.springframework.security.core.context.SecurityContext;
3334
import org.springframework.util.StringUtils;
3435
import org.springframework.web.reactive.BindingContext;
3536
import org.springframework.web.reactive.result.method.HandlerMethodArgumentResolverSupport;
@@ -69,9 +70,9 @@ public boolean supportsParameter(MethodParameter parameter) {
6970
public Mono<Object> resolveArgument(MethodParameter parameter, BindingContext bindingContext,
7071
ServerWebExchange exchange) {
7172
ReactiveAdapter adapter = getAdapterRegistry().getAdapter(parameter.getParameterType());
72-
return exchange.getPrincipal()
73-
.ofType(Authentication.class)
74-
.flatMap( a -> {
73+
return ReactiveSecurityContextHolder.getContext()
74+
.map(SecurityContext::getAuthentication)
75+
.flatMap(a -> {
7576
Object p = resolvePrincipal(parameter, a.getPrincipal());
7677
Mono<Object> principal = Mono.justOrEmpty(p);
7778
return adapter == null ? principal : Mono.just(adapter.fromPublisher(principal));

web/src/test/java/org/springframework/security/web/reactive/result/method/annotation/AuthenticationPrincipalArgumentResolverTests.java

Lines changed: 19 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.springframework.expression.BeanResolver;
2727
import org.springframework.security.core.Authentication;
2828
import org.springframework.security.core.annotation.AuthenticationPrincipal;
29+
import org.springframework.security.core.context.ReactiveSecurityContextHolder;
2930
import org.springframework.security.web.method.ResolvableMethod;
3031
import org.springframework.web.reactive.BindingContext;
3132
import org.springframework.web.server.ServerWebExchange;
@@ -82,28 +83,16 @@ public void supportsParameterCurrentUser() {
8283
public void resolveArgumentWhenIsAuthenticationThenObtainsPrincipal() {
8384
MethodParameter parameter = this.authenticationPrincipal.arg(String.class);
8485
when(authentication.getPrincipal()).thenReturn("user");
85-
when(exchange.getPrincipal()).thenReturn(Mono.just(authentication));
8686

87-
Mono<Object> argument = resolver.resolveArgument(parameter, bindingContext, exchange);
87+
Mono<Object> argument = resolver.resolveArgument(parameter, bindingContext, exchange)
88+
.subscriberContext(ReactiveSecurityContextHolder.withAuthentication(authentication));
8889

8990
assertThat(argument.block()).isEqualTo(authentication.getPrincipal());
9091
}
9192

92-
@Test
93-
public void resolveArgumentWhenIsNotAuthenticationThenMonoEmpty() {
94-
MethodParameter parameter = this.authenticationPrincipal.arg(String.class);
95-
when(exchange.getPrincipal()).thenReturn(Mono.just(() -> ""));
96-
97-
Mono<Object> argument = resolver.resolveArgument(parameter, bindingContext, exchange);
98-
99-
assertThat(argument).isNotNull();
100-
assertThat(argument.block()).isNull();
101-
}
102-
10393
@Test
10494
public void resolveArgumentWhenIsEmptyThenMonoEmpty() {
10595
MethodParameter parameter = this.authenticationPrincipal.arg(String.class);
106-
when(exchange.getPrincipal()).thenReturn(Mono.empty());
10796

10897
Mono<Object> argument = resolver.resolveArgument(parameter, bindingContext, exchange);
10998

@@ -115,9 +104,9 @@ public void resolveArgumentWhenIsEmptyThenMonoEmpty() {
115104
public void resolveArgumentWhenMonoIsAuthenticationThenObtainsPrincipal() {
116105
MethodParameter parameter = this.authenticationPrincipal.arg(Mono.class, String.class);
117106
when(authentication.getPrincipal()).thenReturn("user");
118-
when(exchange.getPrincipal()).thenReturn(Mono.just(authentication));
119107

120-
Mono<Object> argument = resolver.resolveArgument(parameter, bindingContext, exchange);
108+
Mono<Object> argument = resolver.resolveArgument(parameter, bindingContext, exchange)
109+
.subscriberContext(ReactiveSecurityContextHolder.withAuthentication(authentication));
121110

122111
assertThat(argument.cast(Mono.class).block().block()).isEqualTo(authentication.getPrincipal());
123112
}
@@ -126,9 +115,9 @@ public void resolveArgumentWhenMonoIsAuthenticationThenObtainsPrincipal() {
126115
public void resolveArgumentWhenMonoIsAuthenticationAndNoGenericThenObtainsPrincipal() {
127116
MethodParameter parameter = ResolvableMethod.on(getClass()).named("authenticationPrincipalNoGeneric").build().arg(Mono.class);
128117
when(authentication.getPrincipal()).thenReturn("user");
129-
when(exchange.getPrincipal()).thenReturn(Mono.just(authentication));
130118

131-
Mono<Object> argument = resolver.resolveArgument(parameter, bindingContext, exchange);
119+
Mono<Object> argument = resolver.resolveArgument(parameter, bindingContext, exchange)
120+
.subscriberContext(ReactiveSecurityContextHolder.withAuthentication(authentication));
132121

133122
assertThat(argument.cast(Mono.class).block().block()).isEqualTo(authentication.getPrincipal());
134123
}
@@ -138,9 +127,9 @@ public void resolveArgumentWhenSpelThenObtainsPrincipal() {
138127
MyUser user = new MyUser(3L);
139128
MethodParameter parameter = this.spel.arg(Long.class);
140129
when(authentication.getPrincipal()).thenReturn(user);
141-
when(exchange.getPrincipal()).thenReturn(Mono.just(authentication));
142130

143-
Mono<Object> argument = resolver.resolveArgument(parameter, bindingContext, exchange);
131+
Mono<Object> argument = resolver.resolveArgument(parameter, bindingContext, exchange)
132+
.subscriberContext(ReactiveSecurityContextHolder.withAuthentication(authentication));
144133

145134
assertThat(argument.block()).isEqualTo(user.getId());
146135
}
@@ -150,10 +139,10 @@ public void resolveArgumentWhenBeanThenObtainsPrincipal() throws Exception {
150139
MyUser user = new MyUser(3L);
151140
MethodParameter parameter = this.bean.arg(Long.class);
152141
when(authentication.getPrincipal()).thenReturn(user);
153-
when(exchange.getPrincipal()).thenReturn(Mono.just(authentication));
154142
when(this.beanResolver.resolve(any(), eq("beanName"))).thenReturn(new Bean());
155143

156-
Mono<Object> argument = resolver.resolveArgument(parameter, bindingContext, exchange);
144+
Mono<Object> argument = resolver.resolveArgument(parameter, bindingContext, exchange)
145+
.subscriberContext(ReactiveSecurityContextHolder.withAuthentication(authentication));
157146

158147
assertThat(argument.block()).isEqualTo(user.getId());
159148
}
@@ -162,9 +151,9 @@ public void resolveArgumentWhenBeanThenObtainsPrincipal() throws Exception {
162151
public void resolveArgumentWhenMetaThenObtainsPrincipal() {
163152
MethodParameter parameter = this.meta.arg(String.class);
164153
when(authentication.getPrincipal()).thenReturn("user");
165-
when(exchange.getPrincipal()).thenReturn(Mono.just(authentication));
166154

167-
Mono<Object> argument = resolver.resolveArgument(parameter, bindingContext, exchange);
155+
Mono<Object> argument = resolver.resolveArgument(parameter, bindingContext, exchange)
156+
.subscriberContext(ReactiveSecurityContextHolder.withAuthentication(authentication));
168157

169158
assertThat(argument.block()).isEqualTo("user");
170159
}
@@ -173,9 +162,9 @@ public void resolveArgumentWhenMetaThenObtainsPrincipal() {
173162
public void resolveArgumentWhenErrorOnInvalidTypeImplicit() {
174163
MethodParameter parameter = ResolvableMethod.on(getClass()).named("errorOnInvalidTypeWhenImplicit").build().arg(Integer.class);
175164
when(authentication.getPrincipal()).thenReturn("user");
176-
when(exchange.getPrincipal()).thenReturn(Mono.just(authentication));
177165

178-
Mono<Object> argument = resolver.resolveArgument(parameter, bindingContext, exchange);
166+
Mono<Object> argument = resolver.resolveArgument(parameter, bindingContext, exchange)
167+
.subscriberContext(ReactiveSecurityContextHolder.withAuthentication(authentication));
179168

180169
assertThat(argument.block()).isNull();
181170
}
@@ -184,9 +173,9 @@ public void resolveArgumentWhenErrorOnInvalidTypeImplicit() {
184173
public void resolveArgumentWhenErrorOnInvalidTypeExplicitFalse() {
185174
MethodParameter parameter = ResolvableMethod.on(getClass()).named("errorOnInvalidTypeWhenExplicitFalse").build().arg(Integer.class);
186175
when(authentication.getPrincipal()).thenReturn("user");
187-
when(exchange.getPrincipal()).thenReturn(Mono.just(authentication));
188176

189-
Mono<Object> argument = resolver.resolveArgument(parameter, bindingContext, exchange);
177+
Mono<Object> argument = resolver.resolveArgument(parameter, bindingContext, exchange)
178+
.subscriberContext(ReactiveSecurityContextHolder.withAuthentication(authentication));
190179

191180
assertThat(argument.block()).isNull();
192181
}
@@ -195,9 +184,9 @@ public void resolveArgumentWhenErrorOnInvalidTypeExplicitFalse() {
195184
public void resolveArgumentWhenErrorOnInvalidTypeExplicitTrue() {
196185
MethodParameter parameter = ResolvableMethod.on(getClass()).named("errorOnInvalidTypeWhenExplicitTrue").build().arg(Integer.class);
197186
when(authentication.getPrincipal()).thenReturn("user");
198-
when(exchange.getPrincipal()).thenReturn(Mono.just(authentication));
199187

200-
Mono<Object> argument = resolver.resolveArgument(parameter, bindingContext, exchange);
188+
Mono<Object> argument = resolver.resolveArgument(parameter, bindingContext, exchange)
189+
.subscriberContext(ReactiveSecurityContextHolder.withAuthentication(authentication));
201190

202191
assertThatThrownBy(() -> argument.block()).isInstanceOf(ClassCastException.class);
203192
}

0 commit comments

Comments
 (0)