Do not resolve Principal argument if annotated
Closes gh-25780
This commit is contained in:
parent
52084ed954
commit
10eb5bde59
|
@ -19,6 +19,7 @@ package org.springframework.web.servlet.mvc.method.annotation;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.security.Principal;
|
||||
import java.time.ZoneId;
|
||||
import java.util.Locale;
|
||||
|
@ -84,12 +85,13 @@ public class ServletRequestMethodArgumentResolver implements HandlerMethodArgume
|
|||
@Override
|
||||
public boolean supportsParameter(MethodParameter parameter) {
|
||||
Class<?> paramType = parameter.getParameterType();
|
||||
final Annotation[] parameterAnnotations = parameter.getParameterAnnotations();
|
||||
return (WebRequest.class.isAssignableFrom(paramType) ||
|
||||
ServletRequest.class.isAssignableFrom(paramType) ||
|
||||
MultipartRequest.class.isAssignableFrom(paramType) ||
|
||||
HttpSession.class.isAssignableFrom(paramType) ||
|
||||
(pushBuilder != null && pushBuilder.isAssignableFrom(paramType)) ||
|
||||
Principal.class.isAssignableFrom(paramType) ||
|
||||
(Principal.class.isAssignableFrom(paramType) && parameterAnnotations.length == 0) ||
|
||||
InputStream.class.isAssignableFrom(paramType) ||
|
||||
Reader.class.isAssignableFrom(paramType) ||
|
||||
HttpMethod.class == paramType ||
|
||||
|
|
|
@ -18,6 +18,10 @@ package org.springframework.web.servlet.mvc.method.annotation;
|
|||
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.reflect.Method;
|
||||
import java.security.Principal;
|
||||
import java.time.ZoneId;
|
||||
|
@ -122,6 +126,19 @@ public class ServletRequestMethodArgumentResolverTests {
|
|||
assertThat(result).as("Invalid result").isNull();
|
||||
}
|
||||
|
||||
// spring-security already provides the @AuthenticationPrincipal annotation to inject the Principal taken from SecurityContext.getAuthentication.getPrincipal()
|
||||
// but ServletRequestMethodArgumentResolver used to take precedence over @AuthenticationPrincipal resolver org.springframework.security.web.method.annotation.AuthenticationPrincipalArgumentResolver
|
||||
// and we used to get the wrong Principal in methods. See https://github.com/spring-projects/spring-framework/pull/25780
|
||||
@Test
|
||||
public void annotatedPrincipal() throws Exception {
|
||||
Principal principal = () -> "Foo";
|
||||
servletRequest.setUserPrincipal(principal);
|
||||
Method principalMethod = getClass().getMethod("supportedParamsWithAnnotatedPrincipal", Principal.class);
|
||||
|
||||
MethodParameter principalParameter = new MethodParameter(principalMethod, 0);
|
||||
assertThat(resolver.supportsParameter(principalParameter)).as("Principal not supported").isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void locale() throws Exception {
|
||||
Locale locale = Locale.ENGLISH;
|
||||
|
@ -245,6 +262,14 @@ public class ServletRequestMethodArgumentResolverTests {
|
|||
assertThat(result).as("Invalid result").isSameAs(pushBuilder);
|
||||
}
|
||||
|
||||
@Target({ ElementType.PARAMETER })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface PlaceHolder {}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void supportedParamsWithAnnotatedPrincipal(@PlaceHolder Principal p) {
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void supportedParams(ServletRequest p0,
|
||||
|
|
Loading…
Reference in New Issue