Browse Source

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
pull/1228/merge
Rossen Stoyanchev 9 years ago
parent
commit
99cacaa72d
  1. 56
      spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/PrincipalArgumentResolver.java
  2. 1
      spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerAdapter.java
  3. 16
      spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/ServerWebExchangeArgumentResolver.java
  4. 15
      spring-web/src/main/java/org/springframework/web/server/DefaultServerWebExchangeMutativeBuilder.java
  5. 4
      spring-web/src/main/java/org/springframework/web/server/ServerWebExchange.java
  6. 2
      spring-web/src/main/java/org/springframework/web/server/ServerWebExchangeDecorator.java
  7. 4
      spring-web/src/main/java/org/springframework/web/server/adapter/DefaultServerWebExchange.java

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

@ -0,0 +1,56 @@
/*
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.reactive.result.method.annotation;
import java.security.Principal;
import reactor.core.publisher.Mono;
import org.springframework.core.MethodParameter;
import org.springframework.web.reactive.result.method.BindingContext;
import org.springframework.web.reactive.result.method.HandlerMethodArgumentResolver;
import org.springframework.web.server.ServerWebExchange;
/**
* Resolves method argument value of type {@link java.security.Principal}.
*
* @author Rossen Stoyanchev
* @since 5.0
* @see ServerWebExchangeArgumentResolver
*/
public class PrincipalArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
return (Principal.class.isAssignableFrom(parameter.getParameterType()));
}
@Override
public Mono<Object> resolveArgument(MethodParameter parameter, BindingContext context,
ServerWebExchange exchange) {
Class<?> paramType = parameter.getParameterType();
if (Principal.class.isAssignableFrom(paramType)) {
return exchange.getPrincipal().cast(Object.class);
}
else {
// should never happen...
throw new IllegalArgumentException(
"Unknown parameter type: " + paramType + " in method: " + parameter.getMethod());
}
}
}

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

@ -241,6 +241,7 @@ public class RequestMappingHandlerAdapter implements HandlerAdapter, BeanFactory
resolvers.add(new HttpEntityArgumentResolver(getMessageReaders(), getReactiveAdapterRegistry())); resolvers.add(new HttpEntityArgumentResolver(getMessageReaders(), getReactiveAdapterRegistry()));
resolvers.add(new ModelArgumentResolver()); resolvers.add(new ModelArgumentResolver());
resolvers.add(new ServerWebExchangeArgumentResolver()); resolvers.add(new ServerWebExchangeArgumentResolver());
resolvers.add(new PrincipalArgumentResolver());
resolvers.add(new WebSessionArgumentResolver()); resolvers.add(new WebSessionArgumentResolver());
// Custom resolvers // Custom resolvers

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

@ -30,15 +30,17 @@ import org.springframework.web.server.ServerWebExchange;
* <ul> * <ul>
* <li>{@link ServerWebExchange} * <li>{@link ServerWebExchange}
* <li>{@link ServerHttpRequest} * <li>{@link ServerHttpRequest}
* <li>{@link HttpMethod}
* <li>{@link ServerHttpResponse} * <li>{@link ServerHttpResponse}
* <li>{@link HttpMethod}
* </ul> * </ul>
* *
* <p>For the {@code WebSession} see {@link WebSessionArgumentResolver}. * <p>For the {@code WebSession} see {@link WebSessionArgumentResolver}
* and for the {@code Principal} see {@link PrincipalArgumentResolver}.
* *
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
* @since 5.0 * @since 5.0
* @see WebSessionArgumentResolver * @see WebSessionArgumentResolver
* @see PrincipalArgumentResolver
*/ */
public class ServerWebExchangeArgumentResolver implements SyncHandlerMethodArgumentResolver { public class ServerWebExchangeArgumentResolver implements SyncHandlerMethodArgumentResolver {
@ -56,25 +58,23 @@ public class ServerWebExchangeArgumentResolver implements SyncHandlerMethodArgum
ServerWebExchange exchange) { ServerWebExchange exchange) {
Class<?> paramType = parameter.getParameterType(); Class<?> paramType = parameter.getParameterType();
Object value;
if (ServerWebExchange.class.isAssignableFrom(paramType)) { if (ServerWebExchange.class.isAssignableFrom(paramType)) {
value = exchange; return Optional.of(exchange);
} }
else if (ServerHttpRequest.class.isAssignableFrom(paramType)) { else if (ServerHttpRequest.class.isAssignableFrom(paramType)) {
value = exchange.getRequest(); return Optional.of(exchange.getRequest());
} }
else if (ServerHttpResponse.class.isAssignableFrom(paramType)) { else if (ServerHttpResponse.class.isAssignableFrom(paramType)) {
value = exchange.getResponse(); return Optional.of(exchange.getResponse());
} }
else if (HttpMethod.class == paramType) { else if (HttpMethod.class == paramType) {
value = exchange.getRequest().getMethod(); return Optional.of(exchange.getRequest().getMethod());
} }
else { else {
// should never happen... // should never happen...
throw new IllegalArgumentException( throw new IllegalArgumentException(
"Unknown parameter type: " + paramType + " in method: " + parameter.getMethod()); "Unknown parameter type: " + paramType + " in method: " + parameter.getMethod());
} }
return Optional.of(value);
} }
} }

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

@ -16,7 +16,6 @@
package org.springframework.web.server; package org.springframework.web.server;
import java.security.Principal; import java.security.Principal;
import java.util.Optional;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
@ -40,7 +39,7 @@ class DefaultServerWebExchangeMutativeBuilder implements ServerWebExchange.Mutat
private ServerHttpResponse response; private ServerHttpResponse response;
private Principal user; private Mono<Principal> user;
private Mono<WebSession> session; private Mono<WebSession> session;
@ -66,7 +65,7 @@ class DefaultServerWebExchangeMutativeBuilder implements ServerWebExchange.Mutat
} }
@Override @Override
public ServerWebExchange.MutativeBuilder setPrincipal(Principal user) { public ServerWebExchange.MutativeBuilder setPrincipal(Mono<Principal> user) {
this.user = user; this.user = user;
return this; return this;
} }
@ -100,7 +99,7 @@ class DefaultServerWebExchangeMutativeBuilder implements ServerWebExchange.Mutat
private final ServerHttpResponse response; private final ServerHttpResponse response;
private final Principal user; private final Mono<Principal> userMono;
private final Mono<WebSession> session; private final Mono<WebSession> session;
@ -108,13 +107,13 @@ class DefaultServerWebExchangeMutativeBuilder implements ServerWebExchange.Mutat
public MutativeDecorator(ServerWebExchange delegate, public MutativeDecorator(ServerWebExchange delegate,
ServerHttpRequest request, ServerHttpResponse response, Principal user, ServerHttpRequest request, ServerHttpResponse response, Mono<Principal> user,
Mono<WebSession> session, Mono<MultiValueMap<String, String>> formData) { Mono<WebSession> session, Mono<MultiValueMap<String, String>> formData) {
super(delegate); super(delegate);
this.request = request; this.request = request;
this.response = response; this.response = response;
this.user = user; this.userMono = user;
this.session = session; this.session = session;
this.formData = formData; this.formData = formData;
} }
@ -137,8 +136,8 @@ class DefaultServerWebExchangeMutativeBuilder implements ServerWebExchange.Mutat
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public <T extends Principal> Optional<T> getPrincipal() { public <T extends Principal> Mono<T> getPrincipal() {
return (this.user != null ? Optional.of((T) this.user) : getDelegate().getPrincipal()); return (this.userMono != null ? (Mono<T>) this.userMono : getDelegate().getPrincipal());
} }
@Override @Override

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

@ -73,7 +73,7 @@ public interface ServerWebExchange {
/** /**
* Return the authenticated user for the request, if any. * Return the authenticated user for the request, if any.
*/ */
<T extends Principal> Optional<T> getPrincipal(); <T extends Principal> Mono<T> getPrincipal();
/** /**
* Return the form data from the body of the request or an empty {@code Mono} * Return the form data from the body of the request or an empty {@code Mono}
@ -155,7 +155,7 @@ public interface ServerWebExchange {
/** /**
* Set the principal to use. * Set the principal to use.
*/ */
MutativeBuilder setPrincipal(Principal user); MutativeBuilder setPrincipal(Mono<Principal> user);
/** /**
* Set the session to use. * Set the session to use.

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

@ -84,7 +84,7 @@ public class ServerWebExchangeDecorator implements ServerWebExchange {
} }
@Override @Override
public <T extends Principal> Optional<T> getPrincipal() { public <T extends Principal> Mono<T> getPrincipal() {
return getDelegate().getPrincipal(); return getDelegate().getPrincipal();
} }

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

@ -135,8 +135,8 @@ public class DefaultServerWebExchange implements ServerWebExchange {
} }
@Override @Override
public <T extends Principal> Optional<T> getPrincipal() { public <T extends Principal> Mono<T> getPrincipal() {
return Optional.empty(); return Mono.empty();
} }
@Override @Override

Loading…
Cancel
Save