Consistently apply PrincipalMethodArgumentResolver

Closes gh-26117
This commit is contained in:
Rossen Stoyanchev 2020-11-19 21:11:23 +00:00
parent a7cce64e5d
commit 05e3f271b6
3 changed files with 61 additions and 14 deletions

View File

@ -342,6 +342,9 @@ public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExce
resolvers.addAll(getCustomArgumentResolvers());
}
// Catch-all
resolvers.add(new PrincipalMethodArgumentResolver());
return resolvers;
}

View File

@ -681,6 +681,7 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter
}
// Catch-all
resolvers.add(new PrincipalMethodArgumentResolver());
resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), true));
resolvers.add(new ServletModelAttributeMethodProcessor(true));

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 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.
@ -16,7 +16,12 @@
package org.springframework.web.servlet.mvc.method.annotation;
import java.awt.Color;
import java.awt.*;
import java.lang.annotation.Documented;
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.net.URI;
import java.security.Principal;
@ -70,6 +75,7 @@ import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.bind.support.WebArgumentResolver;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletWebRequest;
@ -77,6 +83,7 @@ import org.springframework.web.context.support.GenericWebApplicationContext;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.InvocableHandlerMethod;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.testfixture.servlet.MockHttpServletRequest;
@ -114,6 +121,7 @@ public class RequestMappingHandlerAdapterIntegrationTests {
List<HandlerMethodArgumentResolver> customResolvers = new ArrayList<>();
customResolvers.add(new ServletWebArgumentResolverAdapter(new ColorArgumentResolver()));
customResolvers.add(new CustomPrincipalArgumentResolver());
GenericWebApplicationContext context = new GenericWebApplicationContext();
context.refresh();
@ -145,7 +153,7 @@ public class RequestMappingHandlerAdapterIntegrationTests {
Class<?>[] parameterTypes = new Class<?>[] {int.class, String.class, String.class, String.class, Map.class,
Date.class, Map.class, String.class, String.class, TestBean.class, Errors.class, TestBean.class,
Color.class, HttpServletRequest.class, HttpServletResponse.class, TestBean.class, TestBean.class,
User.class, OtherUser.class, Model.class, UriComponentsBuilder.class};
User.class, OtherUser.class, Principal.class, Model.class, UriComponentsBuilder.class};
String datePattern = "yyyy.MM.dd";
String formattedDate = "2011.03.16";
@ -214,6 +222,7 @@ public class RequestMappingHandlerAdapterIntegrationTests {
assertThat(model.get("customArg") instanceof Color).isTrue();
assertThat(model.get("user").getClass()).isEqualTo(User.class);
assertThat(model.get("otherUser").getClass()).isEqualTo(OtherUser.class);
assertThat(((Principal) model.get("customUser")).getName()).isEqualTo("Custom User");
assertThat(model.get("sessionAttribute")).isSameAs(sessionAttribute);
assertThat(model.get("requestAttribute")).isSameAs(requestAttribute);
@ -476,16 +485,24 @@ public class RequestMappingHandlerAdapterIntegrationTests {
HttpServletResponse response,
@SessionAttribute TestBean sessionAttribute,
@RequestAttribute TestBean requestAttribute,
User user,
@Nullable User user, // gh-26117, gh-26117 (for @Nullable)
@ModelAttribute OtherUser otherUser,
@AuthenticationPrincipal Principal customUser, // gh-25780
Model model,
UriComponentsBuilder builder) {
model.addAttribute("cookie", cookieV).addAttribute("pathvar", pathvarV).addAttribute("header", headerV)
.addAttribute("systemHeader", systemHeader).addAttribute("headerMap", headerMap)
.addAttribute("dateParam", dateParam).addAttribute("paramMap", paramMap)
.addAttribute("paramByConvention", paramByConvention).addAttribute("value", value)
.addAttribute("customArg", customArg).addAttribute(user)
model.addAttribute("cookie", cookieV)
.addAttribute("pathvar", pathvarV)
.addAttribute("header", headerV)
.addAttribute("systemHeader", systemHeader)
.addAttribute("headerMap", headerMap)
.addAttribute("dateParam", dateParam)
.addAttribute("paramMap", paramMap)
.addAttribute("paramByConvention", paramByConvention)
.addAttribute("value", value)
.addAttribute("customArg", customArg)
.addAttribute(user)
.addAttribute("customUser", customUser)
.addAttribute("sessionAttribute", sessionAttribute)
.addAttribute("requestAttribute", requestAttribute)
.addAttribute("url", builder.path("/path").build().toUri());
@ -520,10 +537,15 @@ public class RequestMappingHandlerAdapterIntegrationTests {
Model model,
UriComponentsBuilder builder) {
model.addAttribute("cookie", cookieV).addAttribute("pathvar", pathvarV).addAttribute("header", headerV)
.addAttribute("systemHeader", systemHeader).addAttribute("headerMap", headerMap)
.addAttribute("dateParam", dateParam).addAttribute("paramMap", paramMap)
.addAttribute("paramByConvention", paramByConvention).addAttribute("value", value)
model.addAttribute("cookie", cookieV)
.addAttribute("pathvar", pathvarV)
.addAttribute("header", headerV)
.addAttribute("systemHeader", systemHeader)
.addAttribute("headerMap", headerMap)
.addAttribute("dateParam", dateParam)
.addAttribute("paramMap", paramMap)
.addAttribute("paramByConvention", paramByConvention)
.addAttribute("value", value)
.addAttribute("customArg", customArg).addAttribute(user)
.addAttribute("sessionAttribute", sessionAttribute)
.addAttribute("requestAttribute", requestAttribute)
@ -598,7 +620,6 @@ public class RequestMappingHandlerAdapterIntegrationTests {
}
}
private static class User implements Principal {
@Override
@ -616,4 +637,26 @@ public class RequestMappingHandlerAdapterIntegrationTests {
}
}
private static class CustomPrincipalArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
return (Principal.class.isAssignableFrom(parameter.getParameterType()) &&
parameter.hasParameterAnnotation(AuthenticationPrincipal.class));
}
@Nullable
@Override
public Object resolveArgument(
MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) {
return (Principal) () -> "Custom User";
}
}
@Target({ ElementType.PARAMETER, ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AuthenticationPrincipal {}
}