Check If toBuilder Is Implemented
Since RC1 is right around the corner, let's change the API footprint as little as possible by using reflection to check if a class has declared toBuilder themselves. If they have, we can assume that that class's builder will produce that class. Issue gh-18052
This commit is contained in:
+25
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2004-present 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.authentication;
|
||||
|
||||
public class NonBuildableAuthenticationToken extends TestingAuthenticationToken {
|
||||
|
||||
public NonBuildableAuthenticationToken(String user, String password, String... authorities) {
|
||||
super(user, password, authorities);
|
||||
}
|
||||
|
||||
}
|
||||
+7
-2
@@ -17,6 +17,7 @@
|
||||
package org.springframework.security.oauth2.server.resource.web.authentication;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -56,7 +57,6 @@ import org.springframework.security.web.context.RequestAttributeSecurityContextR
|
||||
import org.springframework.security.web.context.SecurityContextRepository;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
|
||||
@@ -214,7 +214,12 @@ public class BearerTokenAuthenticationFilter extends OncePerRequestFilter {
|
||||
}
|
||||
|
||||
private static boolean declaresToBuilder(Authentication authentication) {
|
||||
return ReflectionUtils.findMethod(authentication.getClass(), "toBuilder") != null;
|
||||
for (Method method : authentication.getClass().getDeclaredMethods()) {
|
||||
if (method.getName().equals("toBuilder") && method.getParameterTypes().length == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+19
@@ -38,6 +38,7 @@ import org.springframework.security.authentication.AuthenticationDetailsSource;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.authentication.AuthenticationManagerResolver;
|
||||
import org.springframework.security.authentication.AuthenticationServiceException;
|
||||
import org.springframework.security.authentication.NonBuildableAuthenticationToken;
|
||||
import org.springframework.security.authentication.SecurityAssertions;
|
||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
@@ -316,6 +317,24 @@ public class BearerTokenAuthenticationFilterTests {
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
@Test
|
||||
void doFilterWhenNonBuildableAuthenticationSubclassThenSkipsToBuilder() throws Exception {
|
||||
TestingAuthenticationToken existingAuthn = new TestingAuthenticationToken("username", "password", "FACTORONE");
|
||||
SecurityContextHolder.setContext(new SecurityContextImpl(existingAuthn));
|
||||
given(this.authenticationManager.authenticate(any()))
|
||||
.willReturn(new NonBuildableAuthenticationToken("username", "password", "FACTORTWO"));
|
||||
given(this.bearerTokenResolver.resolve(any())).willReturn("token");
|
||||
BearerTokenAuthenticationFilter filter = addMocks(
|
||||
new BearerTokenAuthenticationFilter(this.authenticationManager));
|
||||
filter.doFilter(this.request, this.response, this.filterChain);
|
||||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||
// @formatter:off
|
||||
SecurityAssertions.assertThat(authentication).authorities()
|
||||
.extracting(GrantedAuthority::getAuthority)
|
||||
.containsExactly("FACTORTWO");
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setAuthenticationEntryPointWhenNullThenThrowsException() {
|
||||
BearerTokenAuthenticationFilter filter = new BearerTokenAuthenticationFilter(this.authenticationManager);
|
||||
|
||||
+11
-1
@@ -17,6 +17,7 @@
|
||||
package org.springframework.security.web.authentication;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -252,7 +253,7 @@ public abstract class AbstractAuthenticationProcessingFilter extends GenericFilt
|
||||
return;
|
||||
}
|
||||
Authentication current = this.securityContextHolderStrategy.getContext().getAuthentication();
|
||||
if (current != null && current.isAuthenticated()) {
|
||||
if (current != null && current.isAuthenticated() && declaresToBuilder(authenticationResult)) {
|
||||
authenticationResult = authenticationResult.toBuilder()
|
||||
// @formatter:off
|
||||
.authorities((a) -> {
|
||||
@@ -285,6 +286,15 @@ public abstract class AbstractAuthenticationProcessingFilter extends GenericFilt
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean declaresToBuilder(Authentication authentication) {
|
||||
for (Method method : authentication.getClass().getDeclaredMethods()) {
|
||||
if (method.getName().equals("toBuilder") && method.getParameterTypes().length == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether this filter should attempt to process a login request for the
|
||||
* current invocation.
|
||||
|
||||
+11
-1
@@ -17,6 +17,7 @@
|
||||
package org.springframework.security.web.authentication;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -188,7 +189,7 @@ public class AuthenticationFilter extends OncePerRequestFilter {
|
||||
return;
|
||||
}
|
||||
Authentication current = this.securityContextHolderStrategy.getContext().getAuthentication();
|
||||
if (current != null && current.isAuthenticated()) {
|
||||
if (current != null && current.isAuthenticated() && declaresToBuilder(authenticationResult)) {
|
||||
authenticationResult = authenticationResult.toBuilder()
|
||||
// @formatter:off
|
||||
.authorities((a) -> {
|
||||
@@ -215,6 +216,15 @@ public class AuthenticationFilter extends OncePerRequestFilter {
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean declaresToBuilder(Authentication authentication) {
|
||||
for (Method method : authentication.getClass().getDeclaredMethods()) {
|
||||
if (method.getName().equals("toBuilder") && method.getParameterTypes().length == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getAlreadyFilteredAttributeName() {
|
||||
String name = getFilterName();
|
||||
|
||||
+11
-1
@@ -17,6 +17,7 @@
|
||||
package org.springframework.security.web.authentication.preauth;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -208,7 +209,7 @@ public abstract class AbstractPreAuthenticatedProcessingFilter extends GenericFi
|
||||
authenticationRequest.setDetails(this.authenticationDetailsSource.buildDetails(request));
|
||||
Authentication authenticationResult = this.authenticationManager.authenticate(authenticationRequest);
|
||||
Authentication current = this.securityContextHolderStrategy.getContext().getAuthentication();
|
||||
if (current != null && current.isAuthenticated()) {
|
||||
if (current != null && current.isAuthenticated() && declaresToBuilder(authenticationResult)) {
|
||||
authenticationResult = authenticationResult.toBuilder()
|
||||
// @formatter:off
|
||||
.authorities((a) -> {
|
||||
@@ -234,6 +235,15 @@ public abstract class AbstractPreAuthenticatedProcessingFilter extends GenericFi
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean declaresToBuilder(Authentication authentication) {
|
||||
for (Method method : authentication.getClass().getDeclaredMethods()) {
|
||||
if (method.getName().equals("toBuilder") && method.getParameterTypes().length == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts the <code>Authentication</code> instance returned by the authentication
|
||||
* manager into the secure context.
|
||||
|
||||
+11
-1
@@ -17,6 +17,7 @@
|
||||
package org.springframework.security.web.authentication.www;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -190,7 +191,7 @@ public class BasicAuthenticationFilter extends OncePerRequestFilter {
|
||||
if (authenticationIsRequired(username)) {
|
||||
Authentication authResult = this.authenticationManager.authenticate(authRequest);
|
||||
Authentication current = this.securityContextHolderStrategy.getContext().getAuthentication();
|
||||
if (current != null && current.isAuthenticated()) {
|
||||
if (current != null && current.isAuthenticated() && declaresToBuilder(authResult)) {
|
||||
authResult = authResult.toBuilder()
|
||||
// @formatter:off
|
||||
.authorities((a) -> {
|
||||
@@ -234,6 +235,15 @@ public class BasicAuthenticationFilter extends OncePerRequestFilter {
|
||||
chain.doFilter(request, response);
|
||||
}
|
||||
|
||||
private static boolean declaresToBuilder(Authentication authentication) {
|
||||
for (Method method : authentication.getClass().getDeclaredMethods()) {
|
||||
if (method.getName().equals("toBuilder") && method.getParameterTypes().length == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean authenticationIsRequired(String username) {
|
||||
// Only reauthenticate if username doesn't match SecurityContextHolder and user
|
||||
// isn't authenticated (see SEC-53)
|
||||
|
||||
+13
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.security.web.server.authentication;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -141,6 +142,9 @@ public class AuthenticationWebFilter implements WebFilter {
|
||||
if (!current.isAuthenticated()) {
|
||||
return result;
|
||||
}
|
||||
if (!declaresToBuilder(result)) {
|
||||
return result;
|
||||
}
|
||||
return result.toBuilder()
|
||||
// @formatter:off
|
||||
.authorities((a) -> {
|
||||
@@ -158,6 +162,15 @@ public class AuthenticationWebFilter implements WebFilter {
|
||||
}).switchIfEmpty(Mono.just(result));
|
||||
}
|
||||
|
||||
private static boolean declaresToBuilder(Authentication authentication) {
|
||||
for (Method method : authentication.getClass().getDeclaredMethods()) {
|
||||
if (method.getName().equals("toBuilder") && method.getParameterTypes().length == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected Mono<Void> onAuthenticationSuccess(Authentication authentication, WebFilterExchange webFilterExchange) {
|
||||
ServerWebExchange exchange = webFilterExchange.getExchange();
|
||||
SecurityContextImpl securityContext = new SecurityContextImpl();
|
||||
|
||||
+18
@@ -37,6 +37,8 @@ import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.authentication.BadCredentialsException;
|
||||
import org.springframework.security.authentication.InternalAuthenticationServiceException;
|
||||
import org.springframework.security.authentication.NonBuildableAuthenticationToken;
|
||||
import org.springframework.security.authentication.SecurityAssertions;
|
||||
import org.springframework.security.authentication.TestAuthentication;
|
||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
@@ -480,6 +482,22 @@ public class AbstractAuthenticationProcessingFilterTests {
|
||||
.containsExactly(DefaultEqualsGrantedAuthority.AUTHORITY);
|
||||
}
|
||||
|
||||
@Test
|
||||
void doFilterWhenNotOverridingToBuilderThenDoesNotMergeAuthorities() throws Exception {
|
||||
TestingAuthenticationToken existingAuthn = new TestingAuthenticationToken("username", "password", "FACTORONE");
|
||||
SecurityContextHolder.setContext(new SecurityContextImpl(existingAuthn));
|
||||
MockHttpServletRequest request = createMockAuthenticationRequest();
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
MockAuthenticationFilter filter = new MockAuthenticationFilter(
|
||||
new NonBuildableAuthenticationToken("username", "password", "FACTORTWO"));
|
||||
filter.doFilter(request, response, new MockFilterChain(false));
|
||||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||
SecurityAssertions.assertThat(authentication)
|
||||
.authorities()
|
||||
.extracting(GrantedAuthority::getAuthority)
|
||||
.containsExactly("FACTORTWO");
|
||||
}
|
||||
|
||||
/**
|
||||
* https://github.com/spring-projects/spring-security/pull/3905
|
||||
*/
|
||||
|
||||
+22
@@ -37,6 +37,8 @@ import org.springframework.mock.web.MockHttpSession;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.authentication.AuthenticationManagerResolver;
|
||||
import org.springframework.security.authentication.BadCredentialsException;
|
||||
import org.springframework.security.authentication.NonBuildableAuthenticationToken;
|
||||
import org.springframework.security.authentication.SecurityAssertions;
|
||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
@@ -348,6 +350,26 @@ public class AuthenticationFilterTests {
|
||||
.containsExactlyInAnyOrder(DefaultEqualsGrantedAuthority.AUTHORITY);
|
||||
}
|
||||
|
||||
@Test
|
||||
void doFilterWhenNotOverridingToBuilderThenDoesNotMergeAuthorities() throws Exception {
|
||||
TestingAuthenticationToken existingAuthn = new TestingAuthenticationToken("username", "password", "FACTORONE");
|
||||
SecurityContextHolder.setContext(new SecurityContextImpl(existingAuthn));
|
||||
given(this.authenticationConverter.convert(any())).willReturn(existingAuthn);
|
||||
given(this.authenticationManager.authenticate(any()))
|
||||
.willReturn(new NonBuildableAuthenticationToken("user", "password", "FACTORTWO"));
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/");
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
FilterChain chain = new MockFilterChain();
|
||||
AuthenticationFilter filter = new AuthenticationFilter(this.authenticationManager,
|
||||
this.authenticationConverter);
|
||||
filter.doFilter(request, response, chain);
|
||||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||
SecurityAssertions.assertThat(authentication)
|
||||
.authorities()
|
||||
.extracting(GrantedAuthority::getAuthority)
|
||||
.containsExactly("FACTORTWO");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void filterWhenCustomSecurityContextRepositoryAndSuccessfulAuthenticationRepositoryUsed() throws Exception {
|
||||
SecurityContextRepository securityContextRepository = mock(SecurityContextRepository.class);
|
||||
|
||||
+18
@@ -32,6 +32,8 @@ import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.authentication.BadCredentialsException;
|
||||
import org.springframework.security.authentication.NonBuildableAuthenticationToken;
|
||||
import org.springframework.security.authentication.SecurityAssertions;
|
||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
@@ -436,6 +438,22 @@ public class AbstractPreAuthenticatedProcessingFilterTests {
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
@Test
|
||||
void doFilterWhenNotOverridingToBuilderThenDoesNotMergeAuthorities() throws Exception {
|
||||
TestingAuthenticationToken existingAuthn = new TestingAuthenticationToken("username", "password", "FACTORONE");
|
||||
SecurityContextHolder.setContext(new SecurityContextImpl(existingAuthn));
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
this.filter = createFilterAuthenticatesWith(
|
||||
new NonBuildableAuthenticationToken("username", "password", "FACTORTWO"));
|
||||
this.filter.doFilter(request, response, new MockFilterChain());
|
||||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||
SecurityAssertions.assertThat(authentication)
|
||||
.authorities()
|
||||
.extracting(GrantedAuthority::getAuthority)
|
||||
.containsExactly("FACTORTWO");
|
||||
}
|
||||
|
||||
private AbstractPreAuthenticatedProcessingFilter createFilterAuthenticatesWith(Authentication authentication) {
|
||||
ConcretePreAuthenticatedProcessingFilter filter = new ConcretePreAuthenticatedProcessingFilter();
|
||||
filter.setRequiresAuthenticationRequestMatcher(AnyRequestMatcher.INSTANCE);
|
||||
|
||||
+21
@@ -36,6 +36,8 @@ import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.mock.web.MockHttpSession;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.authentication.BadCredentialsException;
|
||||
import org.springframework.security.authentication.NonBuildableAuthenticationToken;
|
||||
import org.springframework.security.authentication.SecurityAssertions;
|
||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
@@ -539,6 +541,25 @@ public class BasicAuthenticationFilterTests {
|
||||
.containsExactly(DefaultEqualsGrantedAuthority.AUTHORITY);
|
||||
}
|
||||
|
||||
@Test
|
||||
void doFilterWhenNotOverridingToBuilderThenDoesNotMergeAuthorities() throws Exception {
|
||||
TestingAuthenticationToken existingAuthn = new TestingAuthenticationToken("username", "password", "FACTORONE");
|
||||
SecurityContextHolder.setContext(new SecurityContextImpl(existingAuthn));
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.addHeader(HttpHeaders.AUTHORIZATION, "Basic " + CodecTestUtils.encodeBase64("a:b"));
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
AuthenticationManager manager = mock(AuthenticationManager.class);
|
||||
given(manager.authenticate(any()))
|
||||
.willReturn(new NonBuildableAuthenticationToken("username", "password", "FACTORTWO"));
|
||||
BasicAuthenticationFilter filter = new BasicAuthenticationFilter(manager);
|
||||
filter.doFilter(request, response, new MockFilterChain());
|
||||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||
SecurityAssertions.assertThat(authentication)
|
||||
.authorities()
|
||||
.extracting(GrantedAuthority::getAuthority)
|
||||
.containsExactly("FACTORTWO");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doFilterWhenCustomAuthenticationConverterRequestThenAuthenticate() throws Exception {
|
||||
this.filter.setAuthenticationConverter(new TestAuthenticationConverter());
|
||||
|
||||
+27
@@ -25,8 +25,10 @@ import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.security.authentication.BadCredentialsException;
|
||||
import org.springframework.security.authentication.NonBuildableAuthenticationToken;
|
||||
import org.springframework.security.authentication.ReactiveAuthenticationManager;
|
||||
import org.springframework.security.authentication.ReactiveAuthenticationManagerResolver;
|
||||
import org.springframework.security.authentication.SecurityAssertions;
|
||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
@@ -230,6 +232,31 @@ public class AuthenticationWebFilterTests {
|
||||
.containsExactly(DefaultEqualsGrantedAuthority.AUTHORITY);
|
||||
}
|
||||
|
||||
@Test
|
||||
void doFilterWhenNotOverridingToBuilderThenDoesNotMergeAuthorities() throws Exception {
|
||||
TestingAuthenticationToken existingAuthn = new TestingAuthenticationToken("username", "password", "FACTORONE");
|
||||
given(this.authenticationManager.authenticate(any()))
|
||||
.willReturn(Mono.just(new NonBuildableAuthenticationToken("user", "password", "FACTORTWO")));
|
||||
given(this.securityContextRepository.save(any(), any())).willReturn(Mono.empty());
|
||||
this.filter = new AuthenticationWebFilter(this.authenticationManager);
|
||||
this.filter.setSecurityContextRepository(this.securityContextRepository);
|
||||
WebTestClient client = WebTestClientBuilder.bindToWebFilters(new RunAsWebFilter(existingAuthn), this.filter)
|
||||
.build();
|
||||
client.get()
|
||||
.uri("/")
|
||||
.headers((headers) -> headers.setBasicAuth("test", "this"))
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.isOk();
|
||||
ArgumentCaptor<SecurityContext> context = ArgumentCaptor.forClass(SecurityContext.class);
|
||||
verify(this.securityContextRepository).save(any(), context.capture());
|
||||
Authentication authentication = context.getValue().getAuthentication();
|
||||
SecurityAssertions.assertThat(authentication)
|
||||
.authorities()
|
||||
.extracting(GrantedAuthority::getAuthority)
|
||||
.containsExactly("FACTORTWO");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void filterWhenAuthenticationManagerResolverDefaultsAndAuthenticationFailThenUnauthorized() {
|
||||
given(this.authenticationManager.authenticate(any()))
|
||||
|
||||
Reference in New Issue
Block a user