Skip to content

Commit 570eb01

Browse files
clevertensionjzheaux
authored andcommitted
review phase1
1 parent 678e0b1 commit 570eb01

File tree

7 files changed

+105
-34
lines changed

7 files changed

+105
-34
lines changed

config/src/main/java/org/springframework/security/config/annotation/web/configuration/WebMvcSecurityConfiguration.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2013 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -40,6 +40,7 @@
4040
* {@link HandlerMethodArgumentResolver}.
4141
*
4242
* @author Rob Winch
43+
* @author Dan Zheng
4344
* @since 3.2
4445
*/
4546
class WebMvcSecurityConfiguration implements WebMvcConfigurer, ApplicationContextAware {

config/src/main/java/org/springframework/security/config/annotation/web/reactive/ServerHttpSecurityConfiguration.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -39,6 +39,7 @@
3939

4040
/**
4141
* @author Rob Winch
42+
* @author Dan Zheng
4243
* @since 5.0
4344
*/
4445
@Configuration

core/src/main/java/org/springframework/security/core/annotation/CurrentSecurityContext.java

+8-16
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2013 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -26,7 +26,7 @@
2626
* argument.
2727
*
2828
* @author Dan Zheng
29-
* @since 5.2.x
29+
* @since 5.2
3030
*
3131
* See: <a href=
3232
* "{@docRoot}/org/springframework/security/web/bind/support/CurrentSecurityContextArgumentResolver.html"
@@ -43,29 +43,21 @@
4343
* @return
4444
*/
4545
boolean errorOnInvalidType() default false;
46+
4647
/**
4748
* If specified will use the provided SpEL expression to resolve the security context. This
4849
* is convenient if users need to transform the result.
4950
*
50-
* <p>
51-
* For example, perhaps the user wants to resolve a CustomUser object that is final
52-
* and is leveraging a UserDetailsService. This can be handled by returning an object
53-
* that looks like:
54-
* </p>
55-
*
5651
* <pre>
57-
* public class CustomUserUserDetails extends User {
58-
* // ...
59-
* public CustomUser getCustomUser() {
60-
* return customUser;
61-
* }
62-
* }
52+
* &#64;CurrentSecurityContext(expression = "authentication") Authentication authentication
6353
* </pre>
6454
*
65-
* Then the user can specify an annotation that looks like:
55+
* <p>
56+
* if you want to retrieve more object from the authentcation, you can see the following the expression
57+
* </p>
6658
*
6759
* <pre>
68-
* &#64;CurrentSecurityContext(expression = "authentication")
60+
* &#64;CurrentSecurityContext(expression = "authentication.principal") Object principal
6961
* </pre>
7062
*
7163
* @return the expression to use.

web/src/main/java/org/springframework/security/web/bind/support/CurrentSecurityContextArgumentResolver.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2013 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -15,6 +15,8 @@
1515
*/
1616
package org.springframework.security.web.bind.support;
1717

18+
import java.lang.annotation.Annotation;
19+
1820
import org.springframework.core.MethodParameter;
1921
import org.springframework.core.annotation.AnnotationUtils;
2022
import org.springframework.expression.BeanResolver;
@@ -32,8 +34,6 @@
3234
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
3335
import org.springframework.web.method.support.ModelAndViewContainer;
3436

35-
import java.lang.annotation.Annotation;
36-
3737
/**
3838
* Allows resolving the {@link SecurityContext} using the
3939
* {@link CurrentSecurityContext} annotation. For example, the following
@@ -69,7 +69,7 @@
6969
* </p>
7070
*
7171
* @author Dan Zheng
72-
* @since 5.2.x
72+
* @since 5.2
7373
*/
7474
public final class CurrentSecurityContextArgumentResolver
7575
implements HandlerMethodArgumentResolver {

web/src/main/java/org/springframework/security/web/reactive/result/method/annotation/CurrentSecurityContextArgumentResolver.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
/**
4141
* Resolves the SecurityContext
4242
* @author Dan Zheng
43-
* @since 5.2.x
43+
* @since 5.2
4444
*/
4545
public class CurrentSecurityContextArgumentResolver extends HandlerMethodArgumentResolverSupport {
4646

web/src/test/java/org/springframework/security/web/bind/support/CurrentSecurityContextArgumentResolverTests.java

+56-8
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,12 @@
1515
*/
1616
package org.springframework.security.web.bind.support;
1717

18+
import java.lang.reflect.Method;
19+
1820
import org.junit.After;
1921
import org.junit.Before;
2022
import org.junit.Test;
23+
2124
import org.springframework.core.MethodParameter;
2225
import org.springframework.expression.spel.SpelEvaluationException;
2326
import org.springframework.security.authentication.TestingAuthenticationToken;
@@ -29,15 +32,12 @@
2932
import org.springframework.security.core.userdetails.User;
3033
import org.springframework.util.ReflectionUtils;
3134

32-
import java.lang.reflect.Method;
33-
3435
import static org.assertj.core.api.Assertions.assertThat;
3536
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
36-
import static org.junit.Assert.fail;
3737

3838
/**
3939
* @author Dan Zheng
40-
* @since 5.2.x
40+
* @since 5.2
4141
*
4242
*/
4343
public class CurrentSecurityContextArgumentResolverTests {
@@ -64,6 +64,22 @@ public void supportsParameterAnnotation() throws Exception {
6464
assertThat(resolver.supportsParameter(showSecurityContextAnnotation())).isTrue();
6565
}
6666

67+
@Test
68+
public void resolveArgumentWithCustomSecurityContext() throws Exception {
69+
String principal = "custom_security_context";
70+
setAuthenticationPrincipalWithCustomSecurityContext(principal);
71+
CustomSecurityContext customSecurityContext = (CustomSecurityContext) resolver.resolveArgument(showAnnotationWithCustomSecurityContext(), null, null, null);
72+
assertThat(customSecurityContext.getAuthentication().getPrincipal()).isEqualTo(principal);
73+
}
74+
75+
@Test
76+
public void resolveArgumentWithCustomSecurityContextTypeMatch() throws Exception {
77+
String principal = "custom_security_context_type_match";
78+
setAuthenticationPrincipalWithCustomSecurityContext(principal);
79+
CustomSecurityContext customSecurityContext = (CustomSecurityContext) resolver.resolveArgument(showAnnotationWithCustomSecurityContext(), null, null, null);
80+
assertThat(customSecurityContext.getAuthentication().getPrincipal()).isEqualTo(principal);
81+
}
82+
6783
@Test
6884
public void resolveArgumentNullAuthentication() throws Exception {
6985
SecurityContext context = SecurityContextHolder.getContext();
@@ -142,10 +158,8 @@ public void resolveArgumentSecurityContextErrorOnInvalidTypeFalse() throws Excep
142158
public void resolveArgumentSecurityContextErrorOnInvalidTypeTrue() throws Exception {
143159
String principal = "invalid_type_true";
144160
setAuthenticationPrincipal(principal);
145-
try {
146-
resolver.resolveArgument(showSecurityContextErrorOnInvalidTypeTrue(), null, null, null);
147-
fail("should not reach here");
148-
} catch(ClassCastException ex) {}
161+
assertThatExceptionOfType(ClassCastException.class).isThrownBy(() -> resolver.resolveArgument(showSecurityContextErrorOnInvalidTypeTrue(), null,
162+
null, null));
149163
}
150164

151165
private MethodParameter showSecurityContextNoAnnotation() {
@@ -156,6 +170,14 @@ private MethodParameter showSecurityContextAnnotation() {
156170
return getMethodParameter("showSecurityContextAnnotation", SecurityContext.class);
157171
}
158172

173+
private MethodParameter showAnnotationWithCustomSecurityContext() {
174+
return getMethodParameter("showAnnotationWithCustomSecurityContext", CustomSecurityContext.class);
175+
}
176+
177+
private MethodParameter showAnnotationWithCustomSecurityContextTypeMatch() {
178+
return getMethodParameter("showAnnotationWithCustomSecurityContextTypeMatch", SecurityContext.class);
179+
}
180+
159181
private MethodParameter showSecurityContextAuthenticationAnnotation() {
160182
return getMethodParameter("showSecurityContextAuthenticationAnnotation", Authentication.class);
161183
}
@@ -197,6 +219,12 @@ public void showSecurityContextNoAnnotation(String user) {
197219
public void showSecurityContextAnnotation(@CurrentSecurityContext SecurityContext context) {
198220
}
199221

222+
public void showAnnotationWithCustomSecurityContext(@CurrentSecurityContext CustomSecurityContext context) {
223+
}
224+
225+
public void showAnnotationWithCustomSecurityContextTypeMatch(@CurrentSecurityContext(errorOnInvalidType = true) SecurityContext context) {
226+
}
227+
200228
public void showSecurityContextAuthenticationAnnotation(@CurrentSecurityContext(expression = "authentication") Authentication authentication) {
201229
}
202230

@@ -229,6 +257,26 @@ private void setAuthenticationPrincipal(Object principal) {
229257
"ROLE_USER"));
230258
}
231259

260+
private void setAuthenticationPrincipalWithCustomSecurityContext(Object principal) {
261+
CustomSecurityContext csc = new CustomSecurityContext();
262+
csc.setAuthentication(new TestingAuthenticationToken(principal, "password",
263+
"ROLE_USER"));
264+
SecurityContextHolder.setContext(csc);
265+
}
266+
267+
static class CustomSecurityContext implements SecurityContext {
268+
private Authentication authentication;
269+
@Override
270+
public Authentication getAuthentication() {
271+
return authentication;
272+
}
273+
274+
@Override
275+
public void setAuthentication(Authentication authentication) {
276+
this.authentication = authentication;
277+
}
278+
}
279+
232280
private void setAuthenticationDetail(Object detail) {
233281
TestingAuthenticationToken tat = new TestingAuthenticationToken("user", "password",
234282
"ROLE_USER");

web/src/test/java/org/springframework/security/web/reactive/result/method/annotation/CurrentSecurityContextArgumentResolverTests.java

+32-3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121
import org.junit.runner.RunWith;
2222
import org.mockito.Mock;
2323
import org.mockito.junit.MockitoJUnitRunner;
24+
import reactor.core.publisher.Mono;
25+
import reactor.util.context.Context;
26+
2427
import org.springframework.core.MethodParameter;
2528
import org.springframework.core.ReactiveAdapterRegistry;
2629
import org.springframework.expression.BeanResolver;
@@ -33,15 +36,14 @@
3336
import org.springframework.security.web.method.ResolvableMethod;
3437
import org.springframework.web.reactive.BindingContext;
3538
import org.springframework.web.server.ServerWebExchange;
36-
import reactor.core.publisher.Mono;
37-
import reactor.util.context.Context;
39+
3840
import static org.assertj.core.api.Assertions.assertThat;
3941
import static org.junit.Assert.fail;
4042

4143

4244
/**
4345
* @author Dan Zheng
44-
* @since 5.2.x
46+
* @since 5.2
4547
*/
4648
@RunWith(MockitoJUnitRunner.class)
4749
public class CurrentSecurityContextArgumentResolverTests {
@@ -98,6 +100,17 @@ public void resolveArgumentWithSecurityContext() throws Exception {
98100
ReactiveSecurityContextHolder.clearContext();
99101
}
100102

103+
@Test
104+
public void resolveArgumentWithCustomSecurityContext() throws Exception {
105+
MethodParameter parameter = ResolvableMethod.on(getClass()).named("customSecurityContext").build().arg(Mono.class, SecurityContext.class);
106+
Authentication auth = buildAuthenticationWithPrincipal("hello");
107+
Context context = ReactiveSecurityContextHolder.withSecurityContext(Mono.just(new CustomSecurityContext(auth)));
108+
Mono<Object> argument = resolver.resolveArgument(parameter, bindingContext, exchange);
109+
CustomSecurityContext securityContext = (CustomSecurityContext) argument.subscriberContext(context).cast(Mono.class).block().block();
110+
assertThat(securityContext.getAuthentication()).isSameAs(auth);
111+
ReactiveSecurityContextHolder.clearContext();
112+
}
113+
101114
@Test
102115
public void resolveArgumentWithNullAuthentication1() throws Exception {
103116
MethodParameter parameter = ResolvableMethod.on(getClass()).named("securityContext").build().arg(Mono.class, SecurityContext.class);
@@ -216,6 +229,8 @@ public void resolveArgumentErrorOnInvalidTypeWhenExplicitTrue() throws Exception
216229

217230
void securityContext(@CurrentSecurityContext Mono<SecurityContext> monoSecurityContext) {}
218231

232+
void customSecurityContext(@CurrentSecurityContext Mono<SecurityContext> monoSecurityContext) {}
233+
219234
void securityContextWithAuthentication(@CurrentSecurityContext(expression = "authentication") Mono<Authentication> authentication) {}
220235

221236
void securityContextWithDepthPropOptional(@CurrentSecurityContext(expression = "authentication?.principal") Mono<Object> principal) {}
@@ -230,7 +245,21 @@ void errorOnInvalidTypeWhenExplicitFalse(@CurrentSecurityContext(errorOnInvalidT
230245

231246
void errorOnInvalidTypeWhenExplicitTrue(@CurrentSecurityContext(errorOnInvalidType = true) Mono<String> implicit) {}
232247

248+
static class CustomSecurityContext implements SecurityContext {
249+
private Authentication authentication;
250+
public CustomSecurityContext(Authentication authentication) {
251+
this.authentication = authentication;
252+
}
253+
@Override
254+
public Authentication getAuthentication() {
255+
return authentication;
256+
}
233257

258+
@Override
259+
public void setAuthentication(Authentication authentication) {
260+
this.authentication = authentication;
261+
}
262+
}
234263
private Authentication buildAuthenticationWithPrincipal(Object principal) {
235264
return new TestingAuthenticationToken(principal, "password",
236265
"ROLE_USER");

0 commit comments

Comments
 (0)