Browse Source
Since Spring Security still needs these methods and classes, we should wait on deprecating them if we can. Instead, this commit changes the original classes to have a boolean property that is currently false, but will switch to true in 6.0. At that time, BearerTokenAuthenticationFilter can change to use the handler. Closes gh-11932pull/12044/head
9 changed files with 114 additions and 271 deletions
@ -1,56 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright 2002-2022 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. |
|
||||||
* You may obtain a copy of the License at |
|
||||||
* |
|
||||||
* https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* |
|
||||||
* Unless required by applicable law or agreed to in writing, software |
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||||
* See the License for the specific language governing permissions and |
|
||||||
* limitations under the License. |
|
||||||
*/ |
|
||||||
|
|
||||||
package org.springframework.security.web.authentication; |
|
||||||
|
|
||||||
import java.io.IOException; |
|
||||||
|
|
||||||
import javax.servlet.ServletException; |
|
||||||
import javax.servlet.http.HttpServletRequest; |
|
||||||
import javax.servlet.http.HttpServletResponse; |
|
||||||
|
|
||||||
import org.springframework.security.authentication.AuthenticationServiceException; |
|
||||||
import org.springframework.security.core.AuthenticationException; |
|
||||||
import org.springframework.security.web.AuthenticationEntryPoint; |
|
||||||
import org.springframework.util.Assert; |
|
||||||
|
|
||||||
/** |
|
||||||
* Adapts a {@link AuthenticationEntryPoint} into a {@link AuthenticationFailureHandler}. |
|
||||||
* When the failure is an {@link AuthenticationServiceException}, it re-throws, to produce |
|
||||||
* an HTTP 500 error. |
|
||||||
* |
|
||||||
* @author Daniel Garnier-Moiroux |
|
||||||
* @since 5.8 |
|
||||||
*/ |
|
||||||
public final class AuthenticationEntryPointFailureHandlerAdapter implements AuthenticationFailureHandler { |
|
||||||
|
|
||||||
private final AuthenticationEntryPoint authenticationEntryPoint; |
|
||||||
|
|
||||||
public AuthenticationEntryPointFailureHandlerAdapter(AuthenticationEntryPoint authenticationEntryPoint) { |
|
||||||
Assert.notNull(authenticationEntryPoint, "authenticationEntryPoint cannot be null"); |
|
||||||
this.authenticationEntryPoint = authenticationEntryPoint; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, |
|
||||||
AuthenticationException failure) throws IOException, ServletException { |
|
||||||
if (AuthenticationServiceException.class.isAssignableFrom(failure.getClass())) { |
|
||||||
throw failure; |
|
||||||
} |
|
||||||
this.authenticationEntryPoint.commence(request, response, failure); |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
@ -1,53 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright 2002-2022 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. |
|
||||||
* You may obtain a copy of the License at |
|
||||||
* |
|
||||||
* https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* |
|
||||||
* Unless required by applicable law or agreed to in writing, software |
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||||
* See the License for the specific language governing permissions and |
|
||||||
* limitations under the License. |
|
||||||
*/ |
|
||||||
|
|
||||||
package org.springframework.security.web.server.authentication; |
|
||||||
|
|
||||||
import reactor.core.publisher.Mono; |
|
||||||
|
|
||||||
import org.springframework.security.authentication.AuthenticationServiceException; |
|
||||||
import org.springframework.security.core.AuthenticationException; |
|
||||||
import org.springframework.security.web.server.ServerAuthenticationEntryPoint; |
|
||||||
import org.springframework.security.web.server.WebFilterExchange; |
|
||||||
import org.springframework.util.Assert; |
|
||||||
|
|
||||||
/** |
|
||||||
* Adapts a {@link ServerAuthenticationEntryPoint} into a |
|
||||||
* {@link ServerAuthenticationFailureHandler}. When the failure is an |
|
||||||
* {@link AuthenticationServiceException}, it re-throws, to produce an HTTP 500 error. |
|
||||||
* |
|
||||||
* @author Daniel Garnier-Moiroux |
|
||||||
* @since 5.8 |
|
||||||
*/ |
|
||||||
public class ServerAuthenticationEntryPointFailureHandlerAdapter implements ServerAuthenticationFailureHandler { |
|
||||||
|
|
||||||
private final ServerAuthenticationEntryPoint authenticationEntryPoint; |
|
||||||
|
|
||||||
public ServerAuthenticationEntryPointFailureHandlerAdapter( |
|
||||||
ServerAuthenticationEntryPoint authenticationEntryPoint) { |
|
||||||
Assert.notNull(authenticationEntryPoint, "authenticationEntryPoint cannot be null"); |
|
||||||
this.authenticationEntryPoint = authenticationEntryPoint; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public Mono<Void> onAuthenticationFailure(WebFilterExchange webFilterExchange, AuthenticationException exception) { |
|
||||||
if (AuthenticationServiceException.class.isAssignableFrom(exception.getClass())) { |
|
||||||
return Mono.error(exception); |
|
||||||
} |
|
||||||
return this.authenticationEntryPoint.commence(webFilterExchange.getExchange(), exception); |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
@ -1,69 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright 2002-2022 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. |
|
||||||
* You may obtain a copy of the License at |
|
||||||
* |
|
||||||
* https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* |
|
||||||
* Unless required by applicable law or agreed to in writing, software |
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||||
* See the License for the specific language governing permissions and |
|
||||||
* limitations under the License. |
|
||||||
*/ |
|
||||||
|
|
||||||
package org.springframework.security.web.authentication; |
|
||||||
|
|
||||||
import java.io.IOException; |
|
||||||
|
|
||||||
import javax.servlet.ServletException; |
|
||||||
import javax.servlet.http.HttpServletRequest; |
|
||||||
import javax.servlet.http.HttpServletResponse; |
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test; |
|
||||||
|
|
||||||
import org.springframework.security.authentication.AuthenticationServiceException; |
|
||||||
import org.springframework.security.core.AuthenticationException; |
|
||||||
import org.springframework.security.web.AuthenticationEntryPoint; |
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType; |
|
||||||
import static org.mockito.Mockito.mock; |
|
||||||
import static org.mockito.Mockito.verify; |
|
||||||
import static org.mockito.Mockito.verifyNoInteractions; |
|
||||||
|
|
||||||
/** |
|
||||||
* @author Daniel Garnier-Moiroux |
|
||||||
* @since 5.8 |
|
||||||
*/ |
|
||||||
class AuthenticationEntryPointFailureHandlerAdapterTest { |
|
||||||
|
|
||||||
private final AuthenticationEntryPoint authenticationEntryPoint = mock(AuthenticationEntryPoint.class); |
|
||||||
|
|
||||||
private final HttpServletRequest request = mock(HttpServletRequest.class); |
|
||||||
|
|
||||||
private final HttpServletResponse response = mock(HttpServletResponse.class); |
|
||||||
|
|
||||||
@Test |
|
||||||
void onAuthenticationFailureThenCommenceAuthentication() throws ServletException, IOException { |
|
||||||
AuthenticationEntryPointFailureHandlerAdapter failureHandler = new AuthenticationEntryPointFailureHandlerAdapter( |
|
||||||
this.authenticationEntryPoint); |
|
||||||
AuthenticationException failure = new AuthenticationException("failed") { |
|
||||||
}; |
|
||||||
failureHandler.onAuthenticationFailure(this.request, this.response, failure); |
|
||||||
verify(this.authenticationEntryPoint).commence(this.request, this.response, failure); |
|
||||||
} |
|
||||||
|
|
||||||
@Test |
|
||||||
void onAuthenticationFailureWithAuthenticationServiceExceptionThenRethrows() { |
|
||||||
AuthenticationEntryPointFailureHandlerAdapter failureHandler = new AuthenticationEntryPointFailureHandlerAdapter( |
|
||||||
this.authenticationEntryPoint); |
|
||||||
AuthenticationException failure = new AuthenticationServiceException("failed"); |
|
||||||
assertThatExceptionOfType(AuthenticationServiceException.class) |
|
||||||
.isThrownBy(() -> failureHandler.onAuthenticationFailure(this.request, this.response, failure)) |
|
||||||
.isSameAs(failure); |
|
||||||
verifyNoInteractions(this.authenticationEntryPoint); |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
@ -0,0 +1,48 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2002-2022 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. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
|
||||||
|
package org.springframework.security.web.authentication; |
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test; |
||||||
|
|
||||||
|
import org.springframework.security.authentication.AuthenticationServiceException; |
||||||
|
import org.springframework.security.web.AuthenticationEntryPoint; |
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThatExceptionOfType; |
||||||
|
import static org.mockito.Mockito.mock; |
||||||
|
|
||||||
|
/** |
||||||
|
* Tests for {@link AuthenticationEntryPointFailureHandler} |
||||||
|
*/ |
||||||
|
public class AuthenticationEntryPointFailureHandlerTests { |
||||||
|
|
||||||
|
@Test |
||||||
|
void onAuthenticationFailureWhenDefaultsThenAuthenticationServiceExceptionSwallowed() throws Exception { |
||||||
|
AuthenticationEntryPoint entryPoint = mock(AuthenticationEntryPoint.class); |
||||||
|
AuthenticationEntryPointFailureHandler handler = new AuthenticationEntryPointFailureHandler(entryPoint); |
||||||
|
handler.onAuthenticationFailure(null, null, new AuthenticationServiceException("fail")); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
void handleWhenRethrowingThenAuthenticationServiceExceptionRethrown() { |
||||||
|
AuthenticationEntryPoint entryPoint = mock(AuthenticationEntryPoint.class); |
||||||
|
AuthenticationEntryPointFailureHandler handler = new AuthenticationEntryPointFailureHandler(entryPoint); |
||||||
|
handler.setRethrowAuthenticationServiceException(true); |
||||||
|
assertThatExceptionOfType(AuthenticationServiceException.class).isThrownBy( |
||||||
|
() -> handler.onAuthenticationFailure(null, null, new AuthenticationServiceException("fail"))); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -1,77 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright 2002-2022 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. |
|
||||||
* You may obtain a copy of the License at |
|
||||||
* |
|
||||||
* https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* |
|
||||||
* Unless required by applicable law or agreed to in writing, software |
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||||
* See the License for the specific language governing permissions and |
|
||||||
* limitations under the License. |
|
||||||
*/ |
|
||||||
|
|
||||||
package org.springframework.security.web.server.authentication; |
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach; |
|
||||||
import org.junit.jupiter.api.Test; |
|
||||||
import reactor.core.publisher.Mono; |
|
||||||
|
|
||||||
import org.springframework.security.authentication.AuthenticationServiceException; |
|
||||||
import org.springframework.security.core.AuthenticationException; |
|
||||||
import org.springframework.security.web.server.ServerAuthenticationEntryPoint; |
|
||||||
import org.springframework.security.web.server.WebFilterExchange; |
|
||||||
import org.springframework.web.server.ServerWebExchange; |
|
||||||
import org.springframework.web.server.WebFilterChain; |
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType; |
|
||||||
import static org.mockito.ArgumentMatchers.any; |
|
||||||
import static org.mockito.BDDMockito.given; |
|
||||||
import static org.mockito.Mockito.mock; |
|
||||||
import static org.mockito.Mockito.verify; |
|
||||||
import static org.mockito.Mockito.verifyNoInteractions; |
|
||||||
|
|
||||||
/** |
|
||||||
* @author Daniel Garnier-Moiroux |
|
||||||
* @since 5.8 |
|
||||||
*/ |
|
||||||
class ServerAuthenticationEntryPointFailureHandlerAdapterTest { |
|
||||||
|
|
||||||
private final ServerAuthenticationEntryPoint serverAuthenticationEntryPoint = mock( |
|
||||||
ServerAuthenticationEntryPoint.class); |
|
||||||
|
|
||||||
private final ServerWebExchange serverWebExchange = mock(ServerWebExchange.class); |
|
||||||
|
|
||||||
private final WebFilterExchange webFilterExchange = new WebFilterExchange(this.serverWebExchange, |
|
||||||
mock(WebFilterChain.class)); |
|
||||||
|
|
||||||
@BeforeEach |
|
||||||
void setUp() { |
|
||||||
given(this.serverAuthenticationEntryPoint.commence(any(), any())).willReturn(Mono.empty()); |
|
||||||
} |
|
||||||
|
|
||||||
@Test |
|
||||||
void onAuthenticationFailureThenCommenceAuthentication() { |
|
||||||
ServerAuthenticationEntryPointFailureHandlerAdapter failureHandler = new ServerAuthenticationEntryPointFailureHandlerAdapter( |
|
||||||
this.serverAuthenticationEntryPoint); |
|
||||||
AuthenticationException failure = new AuthenticationException("failed") { |
|
||||||
}; |
|
||||||
failureHandler.onAuthenticationFailure(this.webFilterExchange, failure).block(); |
|
||||||
verify(this.serverAuthenticationEntryPoint).commence(this.serverWebExchange, failure); |
|
||||||
} |
|
||||||
|
|
||||||
@Test |
|
||||||
void onAuthenticationFailureWithAuthenticationServiceExceptionThenRethrows() { |
|
||||||
ServerAuthenticationEntryPointFailureHandlerAdapter failureHandler = new ServerAuthenticationEntryPointFailureHandlerAdapter( |
|
||||||
this.serverAuthenticationEntryPoint); |
|
||||||
AuthenticationException failure = new AuthenticationServiceException("failed"); |
|
||||||
assertThatExceptionOfType(AuthenticationServiceException.class) |
|
||||||
.isThrownBy(() -> failureHandler.onAuthenticationFailure(this.webFilterExchange, failure).block()) |
|
||||||
.isSameAs(failure); |
|
||||||
verifyNoInteractions(this.serverWebExchange); |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
Loading…
Reference in new issue