Skip to content

Commit 99cacaa

Browse files
committed
Improve reactive support for access to Principal
The method to access the Principal from the ServerWebExchange is now a Mono<Principal> (rather than Optional<Principal>). There is also support for Principal as a controller method argument. Issue: SPR-14680, SPR-14865
1 parent e1a382b commit 99cacaa

File tree

7 files changed

+77
-21
lines changed

7 files changed

+77
-21
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright 2002-2016 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.web.reactive.result.method.annotation;
17+
18+
import java.security.Principal;
19+
20+
import reactor.core.publisher.Mono;
21+
22+
import org.springframework.core.MethodParameter;
23+
import org.springframework.web.reactive.result.method.BindingContext;
24+
import org.springframework.web.reactive.result.method.HandlerMethodArgumentResolver;
25+
import org.springframework.web.server.ServerWebExchange;
26+
27+
/**
28+
* Resolves method argument value of type {@link java.security.Principal}.
29+
*
30+
* @author Rossen Stoyanchev
31+
* @since 5.0
32+
* @see ServerWebExchangeArgumentResolver
33+
*/
34+
public class PrincipalArgumentResolver implements HandlerMethodArgumentResolver {
35+
36+
@Override
37+
public boolean supportsParameter(MethodParameter parameter) {
38+
return (Principal.class.isAssignableFrom(parameter.getParameterType()));
39+
}
40+
41+
@Override
42+
public Mono<Object> resolveArgument(MethodParameter parameter, BindingContext context,
43+
ServerWebExchange exchange) {
44+
45+
Class<?> paramType = parameter.getParameterType();
46+
if (Principal.class.isAssignableFrom(paramType)) {
47+
return exchange.getPrincipal().cast(Object.class);
48+
}
49+
else {
50+
// should never happen...
51+
throw new IllegalArgumentException(
52+
"Unknown parameter type: " + paramType + " in method: " + parameter.getMethod());
53+
}
54+
}
55+
56+
}

spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerAdapter.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ protected List<HandlerMethodArgumentResolver> getDefaultArgumentResolvers() {
241241
resolvers.add(new HttpEntityArgumentResolver(getMessageReaders(), getReactiveAdapterRegistry()));
242242
resolvers.add(new ModelArgumentResolver());
243243
resolvers.add(new ServerWebExchangeArgumentResolver());
244+
resolvers.add(new PrincipalArgumentResolver());
244245
resolvers.add(new WebSessionArgumentResolver());
245246

246247
// Custom resolvers

spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/ServerWebExchangeArgumentResolver.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,17 @@
3030
* <ul>
3131
* <li>{@link ServerWebExchange}
3232
* <li>{@link ServerHttpRequest}
33-
* <li>{@link HttpMethod}
3433
* <li>{@link ServerHttpResponse}
34+
* <li>{@link HttpMethod}
3535
* </ul>
3636
*
37-
* <p>For the {@code WebSession} see {@link WebSessionArgumentResolver}.
37+
* <p>For the {@code WebSession} see {@link WebSessionArgumentResolver}
38+
* and for the {@code Principal} see {@link PrincipalArgumentResolver}.
3839
*
3940
* @author Rossen Stoyanchev
4041
* @since 5.0
4142
* @see WebSessionArgumentResolver
43+
* @see PrincipalArgumentResolver
4244
*/
4345
public class ServerWebExchangeArgumentResolver implements SyncHandlerMethodArgumentResolver {
4446

@@ -56,25 +58,23 @@ public Optional<Object> resolveArgumentValue(MethodParameter parameter, BindingC
5658
ServerWebExchange exchange) {
5759

5860
Class<?> paramType = parameter.getParameterType();
59-
Object value;
6061
if (ServerWebExchange.class.isAssignableFrom(paramType)) {
61-
value = exchange;
62+
return Optional.of(exchange);
6263
}
6364
else if (ServerHttpRequest.class.isAssignableFrom(paramType)) {
64-
value = exchange.getRequest();
65+
return Optional.of(exchange.getRequest());
6566
}
6667
else if (ServerHttpResponse.class.isAssignableFrom(paramType)) {
67-
value = exchange.getResponse();
68+
return Optional.of(exchange.getResponse());
6869
}
6970
else if (HttpMethod.class == paramType) {
70-
value = exchange.getRequest().getMethod();
71+
return Optional.of(exchange.getRequest().getMethod());
7172
}
7273
else {
7374
// should never happen...
7475
throw new IllegalArgumentException(
7576
"Unknown parameter type: " + paramType + " in method: " + parameter.getMethod());
7677
}
77-
return Optional.of(value);
7878
}
7979

8080
}

spring-web/src/main/java/org/springframework/web/server/DefaultServerWebExchangeMutativeBuilder.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
package org.springframework.web.server;
1717

1818
import java.security.Principal;
19-
import java.util.Optional;
2019

2120
import reactor.core.publisher.Mono;
2221

@@ -40,7 +39,7 @@ class DefaultServerWebExchangeMutativeBuilder implements ServerWebExchange.Mutat
4039

4140
private ServerHttpResponse response;
4241

43-
private Principal user;
42+
private Mono<Principal> user;
4443

4544
private Mono<WebSession> session;
4645

@@ -66,7 +65,7 @@ public ServerWebExchange.MutativeBuilder setResponse(ServerHttpResponse response
6665
}
6766

6867
@Override
69-
public ServerWebExchange.MutativeBuilder setPrincipal(Principal user) {
68+
public ServerWebExchange.MutativeBuilder setPrincipal(Mono<Principal> user) {
7069
this.user = user;
7170
return this;
7271
}
@@ -100,21 +99,21 @@ private static class MutativeDecorator extends ServerWebExchangeDecorator {
10099

101100
private final ServerHttpResponse response;
102101

103-
private final Principal user;
102+
private final Mono<Principal> userMono;
104103

105104
private final Mono<WebSession> session;
106105

107106
private final Mono<MultiValueMap<String, String>> formData;
108107

109108

110109
public MutativeDecorator(ServerWebExchange delegate,
111-
ServerHttpRequest request, ServerHttpResponse response, Principal user,
110+
ServerHttpRequest request, ServerHttpResponse response, Mono<Principal> user,
112111
Mono<WebSession> session, Mono<MultiValueMap<String, String>> formData) {
113112

114113
super(delegate);
115114
this.request = request;
116115
this.response = response;
117-
this.user = user;
116+
this.userMono = user;
118117
this.session = session;
119118
this.formData = formData;
120119
}
@@ -137,8 +136,8 @@ public Mono<WebSession> getSession() {
137136

138137
@SuppressWarnings("unchecked")
139138
@Override
140-
public <T extends Principal> Optional<T> getPrincipal() {
141-
return (this.user != null ? Optional.of((T) this.user) : getDelegate().getPrincipal());
139+
public <T extends Principal> Mono<T> getPrincipal() {
140+
return (this.userMono != null ? (Mono<T>) this.userMono : getDelegate().getPrincipal());
142141
}
143142

144143
@Override

spring-web/src/main/java/org/springframework/web/server/ServerWebExchange.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public interface ServerWebExchange {
7373
/**
7474
* Return the authenticated user for the request, if any.
7575
*/
76-
<T extends Principal> Optional<T> getPrincipal();
76+
<T extends Principal> Mono<T> getPrincipal();
7777

7878
/**
7979
* Return the form data from the body of the request or an empty {@code Mono}
@@ -155,7 +155,7 @@ interface MutativeBuilder {
155155
/**
156156
* Set the principal to use.
157157
*/
158-
MutativeBuilder setPrincipal(Principal user);
158+
MutativeBuilder setPrincipal(Mono<Principal> user);
159159

160160
/**
161161
* Set the session to use.

spring-web/src/main/java/org/springframework/web/server/ServerWebExchangeDecorator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ public Mono<WebSession> getSession() {
8484
}
8585

8686
@Override
87-
public <T extends Principal> Optional<T> getPrincipal() {
87+
public <T extends Principal> Mono<T> getPrincipal() {
8888
return getDelegate().getPrincipal();
8989
}
9090

spring-web/src/main/java/org/springframework/web/server/adapter/DefaultServerWebExchange.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,8 @@ public Mono<WebSession> getSession() {
135135
}
136136

137137
@Override
138-
public <T extends Principal> Optional<T> getPrincipal() {
139-
return Optional.empty();
138+
public <T extends Principal> Mono<T> getPrincipal() {
139+
return Mono.empty();
140140
}
141141

142142
@Override

0 commit comments

Comments
 (0)