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
This commit is contained in:
@@ -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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user