parent
f565b23b51
commit
4cbaabb239
|
@ -16,6 +16,10 @@
|
||||||
|
|
||||||
package org.springframework.security.config.annotation.web.reactive;
|
package org.springframework.security.config.annotation.web.reactive;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
@ -28,6 +32,7 @@ import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
import org.springframework.core.Ordered;
|
import org.springframework.core.Ordered;
|
||||||
|
import org.springframework.core.annotation.AliasFor;
|
||||||
import org.springframework.core.annotation.Order;
|
import org.springframework.core.annotation.Order;
|
||||||
import org.springframework.core.io.buffer.DataBuffer;
|
import org.springframework.core.io.buffer.DataBuffer;
|
||||||
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
|
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
|
||||||
|
@ -404,11 +409,28 @@ public class EnableWebFluxSecurityTests {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@RestController
|
@Target({ ElementType.PARAMETER })
|
||||||
static class AuthenticationPrincipalResolver {
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@AuthenticationPrincipal
|
||||||
|
@interface Property {
|
||||||
|
|
||||||
|
@AliasFor(attribute = "expression", annotation = AuthenticationPrincipal.class)
|
||||||
|
String value() default "id";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
interface UsernameResolver {
|
||||||
|
|
||||||
|
String username(@Property("@principalBean.username(#this)") String username);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
static class AuthenticationPrincipalResolver implements UsernameResolver {
|
||||||
|
|
||||||
|
@Override
|
||||||
@GetMapping("/spel")
|
@GetMapping("/spel")
|
||||||
String username(@AuthenticationPrincipal(expression = "@principalBean.username(#this)") String username) {
|
public String username(String username) {
|
||||||
return username;
|
return username;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@ import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import org.springframework.core.MethodParameter;
|
import org.springframework.core.MethodParameter;
|
||||||
import org.springframework.core.annotation.AliasFor;
|
import org.springframework.core.annotation.AliasFor;
|
||||||
|
import org.springframework.core.annotation.AnnotatedMethod;
|
||||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||||
import org.springframework.security.core.annotation.AnnotationTemplateExpressionDefaults;
|
import org.springframework.security.core.annotation.AnnotationTemplateExpressionDefaults;
|
||||||
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
||||||
|
@ -186,10 +187,21 @@ public class AuthenticationPrincipalArgumentResolverTests {
|
||||||
assertThat(this.resolver.resolveArgument(showUserCustomMetaAnnotationTpl(), null)).isEqualTo(principal.id);
|
assertThat(this.resolver.resolveArgument(showUserCustomMetaAnnotationTpl(), null)).isEqualTo(principal.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void resolveArgumentWhenAliasForOnInterfaceThenInherits() {
|
||||||
|
CustomUserPrincipal principal = new CustomUserPrincipal();
|
||||||
|
setAuthenticationPrincipal(principal);
|
||||||
|
assertThat(this.resolver.resolveArgument(showUserNoConcreteAnnotation(), null)).isEqualTo(principal.property);
|
||||||
|
}
|
||||||
|
|
||||||
private MethodParameter showUserNoAnnotation() {
|
private MethodParameter showUserNoAnnotation() {
|
||||||
return getMethodParameter("showUserNoAnnotation", String.class);
|
return getMethodParameter("showUserNoAnnotation", String.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private MethodParameter showUserNoConcreteAnnotation() {
|
||||||
|
return getMethodParameter("showUserNoConcreteAnnotation", String.class);
|
||||||
|
}
|
||||||
|
|
||||||
private MethodParameter showUserAnnotationString() {
|
private MethodParameter showUserAnnotationString() {
|
||||||
return getMethodParameter("showUserAnnotation", String.class);
|
return getMethodParameter("showUserAnnotation", String.class);
|
||||||
}
|
}
|
||||||
|
@ -240,7 +252,7 @@ public class AuthenticationPrincipalArgumentResolverTests {
|
||||||
|
|
||||||
private MethodParameter getMethodParameter(String methodName, Class<?>... paramTypes) {
|
private MethodParameter getMethodParameter(String methodName, Class<?>... paramTypes) {
|
||||||
Method method = ReflectionUtils.findMethod(TestController.class, methodName, paramTypes);
|
Method method = ReflectionUtils.findMethod(TestController.class, methodName, paramTypes);
|
||||||
return new MethodParameter(method, 0);
|
return new AnnotatedMethod(method).getMethodParameters()[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setAuthenticationPrincipal(Object principal) {
|
private void setAuthenticationPrincipal(Object principal) {
|
||||||
|
@ -280,11 +292,32 @@ public class AuthenticationPrincipalArgumentResolverTests {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class TestController {
|
@Target({ ElementType.PARAMETER })
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@AuthenticationPrincipal
|
||||||
|
@interface Property {
|
||||||
|
|
||||||
|
@AliasFor(attribute = "expression", annotation = AuthenticationPrincipal.class)
|
||||||
|
String value() default "id";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private interface TestInterface {
|
||||||
|
|
||||||
|
void showUserNoConcreteAnnotation(@Property("property") String property);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class TestController implements TestInterface {
|
||||||
|
|
||||||
public void showUserNoAnnotation(String user) {
|
public void showUserNoAnnotation(String user) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showUserNoConcreteAnnotation(String user) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public void showUserAnnotation(@AuthenticationPrincipal String user) {
|
public void showUserAnnotation(@AuthenticationPrincipal String user) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,14 +16,17 @@
|
||||||
|
|
||||||
package org.springframework.security.messaging.handler.invocation.reactive;
|
package org.springframework.security.messaging.handler.invocation.reactive;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
import org.springframework.core.MethodParameter;
|
import org.springframework.core.MethodParameter;
|
||||||
import org.springframework.core.annotation.AliasFor;
|
import org.springframework.core.annotation.AliasFor;
|
||||||
|
import org.springframework.core.annotation.AnnotatedMethod;
|
||||||
import org.springframework.core.annotation.SynthesizingMethodParameter;
|
import org.springframework.core.annotation.SynthesizingMethodParameter;
|
||||||
import org.springframework.security.authentication.TestAuthentication;
|
import org.springframework.security.authentication.TestAuthentication;
|
||||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||||
|
@ -128,6 +131,19 @@ public class AuthenticationPrincipalArgumentResolverTests {
|
||||||
assertThat(this.resolver.supportsParameter(arg0("monoUserDetails"))).isFalse();
|
assertThat(this.resolver.supportsParameter(arg0("monoUserDetails"))).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void resolveArgumentWhenAliasForOnInterfaceThenInherits() {
|
||||||
|
CustomUserPrincipal principal = new CustomUserPrincipal();
|
||||||
|
Authentication authentication = new TestingAuthenticationToken(principal, "password", "ROLE_USER");
|
||||||
|
ResolvableMethod method = ResolvableMethod.on(TestController.class)
|
||||||
|
.named("showUserNoConcreteAnnotation")
|
||||||
|
.method();
|
||||||
|
MethodParameter parameter = new AnnotatedMethod(method.method()).getMethodParameters()[0];
|
||||||
|
Mono<Object> result = this.resolver.resolveArgument(parameter, null)
|
||||||
|
.contextWrite(ReactiveSecurityContextHolder.withAuthentication(authentication));
|
||||||
|
assertThat(result.block()).isEqualTo(principal.property);
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
private void monoUserDetails(Mono<UserDetails> user) {
|
private void monoUserDetails(Mono<UserDetails> user) {
|
||||||
}
|
}
|
||||||
|
@ -172,6 +188,8 @@ public class AuthenticationPrincipalArgumentResolverTests {
|
||||||
|
|
||||||
public final int id = 1;
|
public final int id = 1;
|
||||||
|
|
||||||
|
public final String property = "property";
|
||||||
|
|
||||||
public Object getPrincipal() {
|
public Object getPrincipal() {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -195,4 +213,29 @@ public class AuthenticationPrincipalArgumentResolverTests {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Target({ ElementType.PARAMETER })
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@AuthenticationPrincipal
|
||||||
|
@interface Property {
|
||||||
|
|
||||||
|
@AliasFor(attribute = "expression", annotation = AuthenticationPrincipal.class)
|
||||||
|
String value() default "id";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private interface TestInterface {
|
||||||
|
|
||||||
|
void showUserNoConcreteAnnotation(@Property("property") String property);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class TestController implements TestInterface {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showUserNoConcreteAnnotation(String user) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,8 @@ package org.springframework.security.web.method.annotation;
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
|
|
||||||
import org.springframework.core.MethodParameter;
|
import org.springframework.core.MethodParameter;
|
||||||
|
import org.springframework.core.annotation.AnnotationUtils;
|
||||||
|
import org.springframework.core.annotation.MergedAnnotations;
|
||||||
import org.springframework.expression.BeanResolver;
|
import org.springframework.expression.BeanResolver;
|
||||||
import org.springframework.expression.Expression;
|
import org.springframework.expression.Expression;
|
||||||
import org.springframework.expression.ExpressionParser;
|
import org.springframework.expression.ExpressionParser;
|
||||||
|
@ -93,6 +95,8 @@ import org.springframework.web.method.support.ModelAndViewContainer;
|
||||||
*/
|
*/
|
||||||
public final class AuthenticationPrincipalArgumentResolver implements HandlerMethodArgumentResolver {
|
public final class AuthenticationPrincipalArgumentResolver implements HandlerMethodArgumentResolver {
|
||||||
|
|
||||||
|
private final Class<AuthenticationPrincipal> annotationType = AuthenticationPrincipal.class;
|
||||||
|
|
||||||
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
|
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
|
||||||
.getContextHolderStrategy();
|
.getContextHolderStrategy();
|
||||||
|
|
||||||
|
@ -101,6 +105,8 @@ public final class AuthenticationPrincipalArgumentResolver implements HandlerMet
|
||||||
private SecurityAnnotationScanner<AuthenticationPrincipal> scanner = SecurityAnnotationScanners
|
private SecurityAnnotationScanner<AuthenticationPrincipal> scanner = SecurityAnnotationScanners
|
||||||
.requireUnique(AuthenticationPrincipal.class);
|
.requireUnique(AuthenticationPrincipal.class);
|
||||||
|
|
||||||
|
private boolean useAnnotationTemplate = false;
|
||||||
|
|
||||||
private BeanResolver beanResolver;
|
private BeanResolver beanResolver;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -165,6 +171,7 @@ public final class AuthenticationPrincipalArgumentResolver implements HandlerMet
|
||||||
*/
|
*/
|
||||||
public void setTemplateDefaults(AnnotationTemplateExpressionDefaults templateDefaults) {
|
public void setTemplateDefaults(AnnotationTemplateExpressionDefaults templateDefaults) {
|
||||||
this.scanner = SecurityAnnotationScanners.requireUnique(AuthenticationPrincipal.class, templateDefaults);
|
this.scanner = SecurityAnnotationScanners.requireUnique(AuthenticationPrincipal.class, templateDefaults);
|
||||||
|
this.useAnnotationTemplate = templateDefaults != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -174,8 +181,22 @@ public final class AuthenticationPrincipalArgumentResolver implements HandlerMet
|
||||||
* @return the {@link Annotation} that was found or null.
|
* @return the {@link Annotation} that was found or null.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private <T extends Annotation> T findMethodAnnotation(MethodParameter parameter) {
|
private AuthenticationPrincipal findMethodAnnotation(MethodParameter parameter) {
|
||||||
return (T) this.scanner.scan(parameter.getParameter());
|
if (this.useAnnotationTemplate) {
|
||||||
|
return this.scanner.scan(parameter.getParameter());
|
||||||
|
}
|
||||||
|
AuthenticationPrincipal annotation = parameter.getParameterAnnotation(this.annotationType);
|
||||||
|
if (annotation != null) {
|
||||||
|
return annotation;
|
||||||
|
}
|
||||||
|
Annotation[] annotationsToSearch = parameter.getParameterAnnotations();
|
||||||
|
for (Annotation toSearch : annotationsToSearch) {
|
||||||
|
annotation = AnnotationUtils.findAnnotation(toSearch.annotationType(), this.annotationType);
|
||||||
|
if (annotation != null) {
|
||||||
|
return MergedAnnotations.from(toSearch).get(this.annotationType).synthesize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import org.springframework.core.MethodParameter;
|
import org.springframework.core.MethodParameter;
|
||||||
import org.springframework.core.annotation.AliasFor;
|
import org.springframework.core.annotation.AliasFor;
|
||||||
|
import org.springframework.core.annotation.AnnotatedMethod;
|
||||||
import org.springframework.expression.BeanResolver;
|
import org.springframework.expression.BeanResolver;
|
||||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||||
import org.springframework.security.core.annotation.AnnotationTemplateExpressionDefaults;
|
import org.springframework.security.core.annotation.AnnotationTemplateExpressionDefaults;
|
||||||
|
@ -214,10 +215,22 @@ public class AuthenticationPrincipalArgumentResolverTests {
|
||||||
.isEqualTo(this.expectedPrincipal);
|
.isEqualTo(this.expectedPrincipal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void resolveArgumentWhenAliasForOnInterfaceThenInherits() throws Exception {
|
||||||
|
CustomUserPrincipal principal = new CustomUserPrincipal();
|
||||||
|
setAuthenticationPrincipal(principal);
|
||||||
|
assertThat(this.resolver.resolveArgument(showUserNoConcreteAnnotation(), null, null, null))
|
||||||
|
.isEqualTo(principal.property);
|
||||||
|
}
|
||||||
|
|
||||||
private MethodParameter showUserNoAnnotation() {
|
private MethodParameter showUserNoAnnotation() {
|
||||||
return getMethodParameter("showUserNoAnnotation", String.class);
|
return getMethodParameter("showUserNoAnnotation", String.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private MethodParameter showUserNoConcreteAnnotation() {
|
||||||
|
return getMethodParameter("showUserNoConcreteAnnotation", String.class);
|
||||||
|
}
|
||||||
|
|
||||||
private MethodParameter showUserAnnotationString() {
|
private MethodParameter showUserAnnotationString() {
|
||||||
return getMethodParameter("showUserAnnotation", String.class);
|
return getMethodParameter("showUserAnnotation", String.class);
|
||||||
}
|
}
|
||||||
|
@ -272,7 +285,7 @@ public class AuthenticationPrincipalArgumentResolverTests {
|
||||||
|
|
||||||
private MethodParameter getMethodParameter(String methodName, Class<?>... paramTypes) {
|
private MethodParameter getMethodParameter(String methodName, Class<?>... paramTypes) {
|
||||||
Method method = ReflectionUtils.findMethod(TestController.class, methodName, paramTypes);
|
Method method = ReflectionUtils.findMethod(TestController.class, methodName, paramTypes);
|
||||||
return new MethodParameter(method, 0);
|
return new AnnotatedMethod(method).getMethodParameters()[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setAuthenticationPrincipal(Object principal) {
|
private void setAuthenticationPrincipal(Object principal) {
|
||||||
|
@ -295,6 +308,16 @@ public class AuthenticationPrincipalArgumentResolverTests {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Target({ ElementType.PARAMETER })
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@AuthenticationPrincipal
|
||||||
|
@interface Property {
|
||||||
|
|
||||||
|
@AliasFor(attribute = "expression", annotation = AuthenticationPrincipal.class)
|
||||||
|
String value() default "id";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@AuthenticationPrincipal
|
@AuthenticationPrincipal
|
||||||
public @interface CurrentUser2 {
|
public @interface CurrentUser2 {
|
||||||
|
@ -312,11 +335,22 @@ public class AuthenticationPrincipalArgumentResolverTests {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class TestController {
|
public interface TestInterface {
|
||||||
|
|
||||||
|
void showUserNoConcreteAnnotation(@Property("property") String property);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class TestController implements TestInterface {
|
||||||
|
|
||||||
public void showUserNoAnnotation(String user) {
|
public void showUserNoAnnotation(String user) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showUserNoConcreteAnnotation(String user) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public void showUserAnnotation(@AuthenticationPrincipal String user) {
|
public void showUserAnnotation(@AuthenticationPrincipal String user) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ import reactor.core.publisher.Mono;
|
||||||
import org.springframework.core.MethodParameter;
|
import org.springframework.core.MethodParameter;
|
||||||
import org.springframework.core.ReactiveAdapterRegistry;
|
import org.springframework.core.ReactiveAdapterRegistry;
|
||||||
import org.springframework.core.annotation.AliasFor;
|
import org.springframework.core.annotation.AliasFor;
|
||||||
|
import org.springframework.core.annotation.AnnotatedMethod;
|
||||||
import org.springframework.core.annotation.SynthesizingMethodParameter;
|
import org.springframework.core.annotation.SynthesizingMethodParameter;
|
||||||
import org.springframework.expression.BeanResolver;
|
import org.springframework.expression.BeanResolver;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
|
@ -230,6 +231,19 @@ public class AuthenticationPrincipalArgumentResolverTests {
|
||||||
assertThat(result.block()).isEqualTo(principal.id);
|
assertThat(result.block()).isEqualTo(principal.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void resolveArgumentWhenAliasForOnInterfaceThenInherits() {
|
||||||
|
CustomUserPrincipal principal = new CustomUserPrincipal();
|
||||||
|
given(this.authentication.getPrincipal()).willReturn(principal);
|
||||||
|
ResolvableMethod method = ResolvableMethod.on(TestController.class)
|
||||||
|
.named("showUserNoConcreteAnnotation")
|
||||||
|
.build();
|
||||||
|
MethodParameter parameter = new AnnotatedMethod(method.method()).getMethodParameters()[0];
|
||||||
|
Mono<Object> result = this.resolver.resolveArgument(parameter, this.bindingContext, this.exchange)
|
||||||
|
.contextWrite(ReactiveSecurityContextHolder.withAuthentication(this.authentication));
|
||||||
|
assertThat(result.block()).isEqualTo(principal.property);
|
||||||
|
}
|
||||||
|
|
||||||
private MethodParameter arg0(String methodName) {
|
private MethodParameter arg0(String methodName) {
|
||||||
ResolvableMethod method = ResolvableMethod.on(getClass()).named(methodName).build();
|
ResolvableMethod method = ResolvableMethod.on(getClass()).named(methodName).build();
|
||||||
return new SynthesizingMethodParameter(method.method(), 0);
|
return new SynthesizingMethodParameter(method.method(), 0);
|
||||||
|
@ -317,6 +331,8 @@ public class AuthenticationPrincipalArgumentResolverTests {
|
||||||
|
|
||||||
public final int id = 1;
|
public final int id = 1;
|
||||||
|
|
||||||
|
public final String property = "property";
|
||||||
|
|
||||||
public Object getPrincipal() {
|
public Object getPrincipal() {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -340,4 +356,29 @@ public class AuthenticationPrincipalArgumentResolverTests {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Target({ ElementType.PARAMETER })
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@AuthenticationPrincipal
|
||||||
|
@interface Property {
|
||||||
|
|
||||||
|
@AliasFor(attribute = "expression", annotation = AuthenticationPrincipal.class)
|
||||||
|
String value() default "id";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private interface TestInterface {
|
||||||
|
|
||||||
|
void showUserNoConcreteAnnotation(@Property("property") String property);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class TestController implements TestInterface {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showUserNoConcreteAnnotation(String user) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue