Skip to content

Commit 5afc7cb

Browse files
committed
Merge remote-tracking branch 'origin/5.8.x'
2 parents 9090f62 + 099aaa3 commit 5afc7cb

File tree

6 files changed

+127
-4
lines changed

6 files changed

+127
-4
lines changed

etc/checkstyle/checkstyle-suppressions.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,7 @@
3737
<suppress files="WithSecurityContextTestExecutionListenerTests\.java" checks="SpringMethodVisibility"/>
3838
<suppress files="AbstractOAuth2AuthorizationGrantRequestEntityConverter\.java" checks="SpringMethodVisibility"/>
3939
<suppress files="JoseHeader\.java" checks="SpringMethodVisibility"/>
40+
41+
<!-- Lambdas that we can't replace with a method reference because a closure is required -->
42+
<suppress files="BearerTokenAuthenticationFilter\.java" checks="SpringLambda"/>
4043
</suppressions>

oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/web/authentication/BearerTokenAuthenticationFilterTests.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,14 @@
3636
import org.springframework.security.authentication.AuthenticationManagerResolver;
3737
import org.springframework.security.authentication.AuthenticationServiceException;
3838
import org.springframework.security.authentication.TestingAuthenticationToken;
39+
import org.springframework.security.core.AuthenticationException;
3940
import org.springframework.security.core.context.SecurityContext;
4041
import org.springframework.security.core.context.SecurityContextHolderStrategy;
4142
import org.springframework.security.core.context.SecurityContextImpl;
4243
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
4344
import org.springframework.security.oauth2.server.resource.BearerTokenError;
4445
import org.springframework.security.oauth2.server.resource.BearerTokenErrorCodes;
46+
import org.springframework.security.oauth2.server.resource.InvalidBearerTokenException;
4547
import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthenticationToken;
4648
import org.springframework.security.oauth2.server.resource.web.BearerTokenResolver;
4749
import org.springframework.security.web.AuthenticationEntryPoint;
@@ -203,6 +205,19 @@ public void doFilterWhenAuthenticationServiceExceptionThenRethrows() {
203205
.isThrownBy(() -> filter.doFilter(this.request, this.response, this.filterChain));
204206
}
205207

208+
@Test
209+
public void doFilterWhenCustomEntryPointAndAuthenticationErrorThenUses() throws ServletException, IOException {
210+
AuthenticationException exception = new InvalidBearerTokenException("message");
211+
given(this.bearerTokenResolver.resolve(this.request)).willReturn("token");
212+
given(this.authenticationManager.authenticate(any())).willThrow(exception);
213+
BearerTokenAuthenticationFilter filter = addMocks(
214+
new BearerTokenAuthenticationFilter(this.authenticationManager));
215+
AuthenticationEntryPoint entrypoint = mock(AuthenticationEntryPoint.class);
216+
filter.setAuthenticationEntryPoint(entrypoint);
217+
filter.doFilter(this.request, this.response, this.filterChain);
218+
verify(entrypoint).commence(any(), any(), any(InvalidBearerTokenException.class));
219+
}
220+
206221
@Test
207222
public void doFilterWhenCustomAuthenticationDetailsSourceThenUses() throws ServletException, IOException {
208223
given(this.bearerTokenResolver.resolve(this.request)).willReturn("token");

web/src/main/java/org/springframework/security/web/authentication/AuthenticationEntryPointFailureHandler.java

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2019 the original author or authors.
2+
* Copyright 2002-2022 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.
@@ -22,6 +22,7 @@
2222
import jakarta.servlet.http.HttpServletRequest;
2323
import jakarta.servlet.http.HttpServletResponse;
2424

25+
import org.springframework.security.authentication.AuthenticationServiceException;
2526
import org.springframework.security.core.AuthenticationException;
2627
import org.springframework.security.web.AuthenticationEntryPoint;
2728
import org.springframework.util.Assert;
@@ -34,6 +35,8 @@
3435
*/
3536
public class AuthenticationEntryPointFailureHandler implements AuthenticationFailureHandler {
3637

38+
private boolean rethrowAuthenticationServiceException = false;
39+
3740
private final AuthenticationEntryPoint authenticationEntryPoint;
3841

3942
public AuthenticationEntryPointFailureHandler(AuthenticationEntryPoint authenticationEntryPoint) {
@@ -44,7 +47,25 @@ public AuthenticationEntryPointFailureHandler(AuthenticationEntryPoint authentic
4447
@Override
4548
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
4649
AuthenticationException exception) throws IOException, ServletException {
47-
this.authenticationEntryPoint.commence(request, response, exception);
50+
if (!this.rethrowAuthenticationServiceException) {
51+
this.authenticationEntryPoint.commence(request, response, exception);
52+
return;
53+
}
54+
if (!AuthenticationServiceException.class.isAssignableFrom(exception.getClass())) {
55+
this.authenticationEntryPoint.commence(request, response, exception);
56+
return;
57+
}
58+
throw exception;
59+
}
60+
61+
/**
62+
* Set whether to rethrow {@link AuthenticationServiceException}s (defaults to false)
63+
* @param rethrowAuthenticationServiceException whether to rethrow
64+
* {@link AuthenticationServiceException}s
65+
* @since 5.8
66+
*/
67+
public void setRethrowAuthenticationServiceException(boolean rethrowAuthenticationServiceException) {
68+
this.rethrowAuthenticationServiceException = rethrowAuthenticationServiceException;
4869
}
4970

5071
}

web/src/main/java/org/springframework/security/web/server/authentication/ServerAuthenticationEntryPointFailureHandler.java

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2022 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.
@@ -18,6 +18,7 @@
1818

1919
import reactor.core.publisher.Mono;
2020

21+
import org.springframework.security.authentication.AuthenticationServiceException;
2122
import org.springframework.security.core.AuthenticationException;
2223
import org.springframework.security.web.server.ServerAuthenticationEntryPoint;
2324
import org.springframework.security.web.server.WebFilterExchange;
@@ -34,14 +35,32 @@ public class ServerAuthenticationEntryPointFailureHandler implements ServerAuthe
3435

3536
private final ServerAuthenticationEntryPoint authenticationEntryPoint;
3637

38+
private boolean rethrowAuthenticationServiceException = false;
39+
3740
public ServerAuthenticationEntryPointFailureHandler(ServerAuthenticationEntryPoint authenticationEntryPoint) {
3841
Assert.notNull(authenticationEntryPoint, "authenticationEntryPoint cannot be null");
3942
this.authenticationEntryPoint = authenticationEntryPoint;
4043
}
4144

4245
@Override
4346
public Mono<Void> onAuthenticationFailure(WebFilterExchange webFilterExchange, AuthenticationException exception) {
44-
return this.authenticationEntryPoint.commence(webFilterExchange.getExchange(), exception);
47+
if (!this.rethrowAuthenticationServiceException) {
48+
return this.authenticationEntryPoint.commence(webFilterExchange.getExchange(), exception);
49+
}
50+
if (!AuthenticationServiceException.class.isAssignableFrom(exception.getClass())) {
51+
return this.authenticationEntryPoint.commence(webFilterExchange.getExchange(), exception);
52+
}
53+
return Mono.error(exception);
54+
}
55+
56+
/**
57+
* Set whether to rethrow {@link AuthenticationServiceException}s (defaults to false)
58+
* @param rethrowAuthenticationServiceException whether to rethrow
59+
* {@link AuthenticationServiceException}s
60+
* @since 5.8
61+
*/
62+
public void setRethrowAuthenticationServiceException(boolean rethrowAuthenticationServiceException) {
63+
this.rethrowAuthenticationServiceException = rethrowAuthenticationServiceException;
4564
}
4665

4766
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright 2002-2022 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.security.web.authentication;
18+
19+
import org.junit.jupiter.api.Test;
20+
21+
import org.springframework.security.authentication.AuthenticationServiceException;
22+
import org.springframework.security.web.AuthenticationEntryPoint;
23+
24+
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
25+
import static org.mockito.Mockito.mock;
26+
27+
/**
28+
* Tests for {@link AuthenticationEntryPointFailureHandler}
29+
*/
30+
public class AuthenticationEntryPointFailureHandlerTests {
31+
32+
@Test
33+
void onAuthenticationFailureWhenDefaultsThenAuthenticationServiceExceptionSwallowed() throws Exception {
34+
AuthenticationEntryPoint entryPoint = mock(AuthenticationEntryPoint.class);
35+
AuthenticationEntryPointFailureHandler handler = new AuthenticationEntryPointFailureHandler(entryPoint);
36+
handler.onAuthenticationFailure(null, null, new AuthenticationServiceException("fail"));
37+
}
38+
39+
@Test
40+
void handleWhenRethrowingThenAuthenticationServiceExceptionRethrown() {
41+
AuthenticationEntryPoint entryPoint = mock(AuthenticationEntryPoint.class);
42+
AuthenticationEntryPointFailureHandler handler = new AuthenticationEntryPointFailureHandler(entryPoint);
43+
handler.setRethrowAuthenticationServiceException(true);
44+
assertThatExceptionOfType(AuthenticationServiceException.class).isThrownBy(
45+
() -> handler.onAuthenticationFailure(null, null, new AuthenticationServiceException("fail")));
46+
}
47+
48+
}

web/src/test/java/org/springframework/security/web/server/authentication/ServerAuthenticationEntryPointFailureHandlerTests.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,15 @@
2323
import org.mockito.junit.jupiter.MockitoExtension;
2424
import reactor.core.publisher.Mono;
2525

26+
import org.springframework.security.authentication.AuthenticationServiceException;
2627
import org.springframework.security.authentication.BadCredentialsException;
2728
import org.springframework.security.web.server.ServerAuthenticationEntryPoint;
2829
import org.springframework.security.web.server.WebFilterExchange;
2930
import org.springframework.web.server.ServerWebExchange;
3031
import org.springframework.web.server.WebFilterChain;
3132

3233
import static org.assertj.core.api.Assertions.assertThat;
34+
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
3335
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
3436
import static org.mockito.BDDMockito.given;
3537

@@ -68,4 +70,19 @@ public void onAuthenticationFailureWhenInvokedThenDelegatesToEntryPoint() {
6870
assertThat(this.handler.onAuthenticationFailure(this.filterExchange, e)).isEqualTo(result);
6971
}
7072

73+
@Test
74+
void onAuthenticationFailureWhenDefaultsThenAuthenticationServiceExceptionSwallowed() {
75+
AuthenticationServiceException e = new AuthenticationServiceException("fail");
76+
given(this.authenticationEntryPoint.commence(this.exchange, e)).willReturn(Mono.empty());
77+
this.handler.onAuthenticationFailure(this.filterExchange, e).block();
78+
}
79+
80+
@Test
81+
void handleWhenRethrowingThenAuthenticationServiceExceptionRethrown() {
82+
AuthenticationServiceException e = new AuthenticationServiceException("fail");
83+
this.handler.setRethrowAuthenticationServiceException(true);
84+
assertThatExceptionOfType(AuthenticationServiceException.class)
85+
.isThrownBy(() -> this.handler.onAuthenticationFailure(this.filterExchange, e).block());
86+
}
87+
7188
}

0 commit comments

Comments
 (0)