- * Configures default {@link RequestMatcher} verifying the provided endpoint.
- *
- * @param authenticationManager
- * the bean to submit authentication requests to
- * @param filterProcessesUrl
- * the filterProcessesUrl to match request URI against
- */
- public OAuth2ClientAuthenticationFilter(AuthenticationManager authenticationManager, String filterProcessesUrl) {
- this(authenticationManager, new AntPathRequestMatcher(filterProcessesUrl, "POST"));
- }
-
- /**
- * Creates an instance which will authenticate against the supplied
- * {@code AuthenticationManager} and custom {@code RequestMatcher}.
- *
- * @param authenticationManager
- * the bean to submit authentication requests to
- * @param requestMatcher
- * the {@code RequestMatcher} to match {@code HttpServletRequest} against
+ * @param authenticationManager the {@link AuthenticationManager} used for authenticating the client
+ * @param requestMatcher the {@link RequestMatcher} used for matching against the {@code HttpServletRequest}
*/
public OAuth2ClientAuthenticationFilter(AuthenticationManager authenticationManager,
RequestMatcher requestMatcher) {
@@ -92,8 +73,9 @@ public class OAuth2ClientAuthenticationFilter extends OncePerRequestFilter {
Assert.notNull(requestMatcher, "requestMatcher cannot be null");
this.authenticationManager = authenticationManager;
this.requestMatcher = requestMatcher;
- this.authenticationSuccessHandler = this::defaultAuthenticationSuccessHandler;
- this.authenticationFailureHandler = this::defaultAuthenticationFailureHandler;
+ this.authenticationConverter = new ClientSecretBasicAuthenticationConverter();
+ this.authenticationSuccessHandler = this::onAuthenticationSuccess;
+ this.authenticationFailureHandler = this::onAuthenticationFailure;
}
@Override
@@ -101,14 +83,12 @@ public class OAuth2ClientAuthenticationFilter extends OncePerRequestFilter {
throws ServletException, IOException {
if (this.requestMatcher.matches(request)) {
- Authentication authentication = this.authenticationConverter.convert(request);
- if (authentication == null) {
- filterChain.doFilter(request, response);
- return;
- }
try {
- final Authentication result = this.authenticationManager.authenticate(authentication);
- this.authenticationSuccessHandler.onAuthenticationSuccess(request, response, result);
+ Authentication authenticationRequest = this.authenticationConverter.convert(request);
+ if (authenticationRequest != null) {
+ Authentication authenticationResult = this.authenticationManager.authenticate(authenticationRequest);
+ this.authenticationSuccessHandler.onAuthenticationSuccess(request, response, authenticationResult);
+ }
} catch (OAuth2AuthenticationException failed) {
this.authenticationFailureHandler.onAuthenticationFailure(request, response, failed);
return;
@@ -118,10 +98,19 @@ public class OAuth2ClientAuthenticationFilter extends OncePerRequestFilter {
}
/**
- * Used to define custom behaviour on a successful authentication.
+ * Sets the {@link AuthenticationConverter} used for converting a {@link HttpServletRequest} to an {@link OAuth2ClientAuthenticationToken}.
*
- * @param authenticationSuccessHandler
- * the handler to be used
+ * @param authenticationConverter used for converting a {@link HttpServletRequest} to an {@link OAuth2ClientAuthenticationToken}
+ */
+ public final void setAuthenticationConverter(AuthenticationConverter authenticationConverter) {
+ Assert.notNull(authenticationConverter, "authenticationConverter cannot be null");
+ this.authenticationConverter = authenticationConverter;
+ }
+
+ /**
+ * Sets the {@link AuthenticationSuccessHandler} used for handling successful authentications.
+ *
+ * @param authenticationSuccessHandler the {@link AuthenticationSuccessHandler} used for handling successful authentications
*/
public final void setAuthenticationSuccessHandler(AuthenticationSuccessHandler authenticationSuccessHandler) {
Assert.notNull(authenticationSuccessHandler, "authenticationSuccessHandler cannot be null");
@@ -129,39 +118,43 @@ public class OAuth2ClientAuthenticationFilter extends OncePerRequestFilter {
}
/**
- * Used to define custom behaviour on a failed authentication.
+ * Sets the {@link AuthenticationFailureHandler} used for handling failed authentications.
*
- * @param authenticationFailureHandler
- * the handler to be used
+ * @param authenticationFailureHandler the {@link AuthenticationFailureHandler} used for handling failed authentications
*/
public final void setAuthenticationFailureHandler(AuthenticationFailureHandler authenticationFailureHandler) {
Assert.notNull(authenticationFailureHandler, "authenticationFailureHandler cannot be null");
this.authenticationFailureHandler = authenticationFailureHandler;
}
- /**
- * Used to define custom {@link AuthenticationConverter}.
- *
- * @param authenticationConverter
- * the converter to be used
- */
- public final void setAuthenticationConverter(AuthenticationConverter authenticationConverter) {
- Assert.notNull(authenticationConverter, "authenticationConverter cannot be null");
- this.authenticationConverter = authenticationConverter;
- }
-
- private void defaultAuthenticationSuccessHandler(HttpServletRequest request, HttpServletResponse response,
+ private void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) {
- SecurityContextHolder.getContext()
- .setAuthentication(authentication);
+ SecurityContext context = SecurityContextHolder.createEmptyContext();
+ context.setAuthentication(authentication);
+ SecurityContextHolder.setContext(context);
}
- private void defaultAuthenticationFailureHandler(HttpServletRequest request, HttpServletResponse response,
+ private void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException failed) throws IOException {
SecurityContextHolder.clearContext();
- this.errorMessageConverter.write(((OAuth2AuthenticationException) failed).getError(),
- MediaType.APPLICATION_JSON, new ServletServerHttpResponse(response));
+
+ // TODO
+ // The authorization server MAY return an HTTP 401 (Unauthorized) status code
+ // to indicate which HTTP authentication schemes are supported.
+ // If the client attempted to authenticate via the "Authorization" request header field,
+ // the authorization server MUST respond with an HTTP 401 (Unauthorized) status code and
+ // include the "WWW-Authenticate" response header field
+ // matching the authentication scheme used by the client.
+
+ OAuth2Error error = ((OAuth2AuthenticationException) failed).getError();
+ ServletServerHttpResponse httpResponse = new ServletServerHttpResponse(response);
+ if (OAuth2ErrorCodes.INVALID_CLIENT.equals(error.getErrorCode())) {
+ httpResponse.setStatusCode(HttpStatus.UNAUTHORIZED);
+ } else {
+ httpResponse.setStatusCode(HttpStatus.BAD_REQUEST);
+ }
+ this.errorHttpResponseConverter.write(error, null, httpResponse);
}
}
diff --git a/core/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2ClientAuthenticationProviderTests.java b/core/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2ClientAuthenticationProviderTests.java
index 099e4be..03c39dd 100644
--- a/core/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2ClientAuthenticationProviderTests.java
+++ b/core/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2ClientAuthenticationProviderTests.java
@@ -18,11 +18,12 @@ package org.springframework.security.oauth2.server.authorization.authentication;
import org.junit.Before;
import org.junit.Test;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
+import org.springframework.security.oauth2.core.OAuth2ErrorCodes;
import org.springframework.security.oauth2.server.authorization.client.InMemoryRegisteredClientRepository;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients;
-import java.util.Collections;
+
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
@@ -30,25 +31,25 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
* Tests for {@link OAuth2ClientAuthenticationProvider}.
*
* @author Patryk Kostrzewa
+ * @author Joe Grandja
*/
public class OAuth2ClientAuthenticationProviderTests {
-
private RegisteredClient registeredClient;
private RegisteredClientRepository registeredClientRepository;
private OAuth2ClientAuthenticationProvider authenticationProvider;
@Before
public void setUp() {
- this.registeredClient = TestRegisteredClients.registeredClient()
- .build();
+ this.registeredClient = TestRegisteredClients.registeredClient().build();
this.registeredClientRepository = new InMemoryRegisteredClientRepository(this.registeredClient);
this.authenticationProvider = new OAuth2ClientAuthenticationProvider(this.registeredClientRepository);
}
@Test
- public void constructorWhenRegisteredClientRepositoryIsNullThenThrowIllegalArgumentException() {
- assertThatThrownBy(() -> new OAuth2ClientAuthenticationProvider(null)).isInstanceOf(
- IllegalArgumentException.class);
+ public void constructorWhenRegisteredClientRepositoryNullThenThrowIllegalArgumentException() {
+ assertThatThrownBy(() -> new OAuth2ClientAuthenticationProvider(null))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessage("registeredClientRepository cannot be null");
}
@Test
@@ -57,34 +58,36 @@ public class OAuth2ClientAuthenticationProviderTests {
}
@Test
- public void authenticateWhenNullCredentialsThenThrowOAuth2AuthorizationException() {
- assertThatThrownBy(() -> {
- this.authenticationProvider.authenticate(new OAuth2ClientAuthenticationToken("id", null));
- }).isInstanceOf(OAuth2AuthenticationException.class);
+ public void authenticateWhenInvalidClientIdThenThrowOAuth2AuthenticationException() {
+ OAuth2ClientAuthenticationToken authentication = new OAuth2ClientAuthenticationToken(
+ this.registeredClient.getClientId() + "-invalid", this.registeredClient.getClientSecret());
+ assertThatThrownBy(() -> this.authenticationProvider.authenticate(authentication))
+ .isInstanceOf(OAuth2AuthenticationException.class)
+ .extracting(ex -> ((OAuth2AuthenticationException) ex).getError())
+ .extracting("errorCode")
+ .isEqualTo(OAuth2ErrorCodes.INVALID_CLIENT);
}
@Test
- public void authenticateWhenNullRegisteredClientThenThrowOAuth2AuthorizationException() {
- assertThatThrownBy(() -> {
- this.authenticationProvider.authenticate(new OAuth2ClientAuthenticationToken("id", "secret"));
- }).isInstanceOf(OAuth2AuthenticationException.class);
+ public void authenticateWhenInvalidClientSecretThenThrowOAuth2AuthenticationException() {
+ OAuth2ClientAuthenticationToken authentication = new OAuth2ClientAuthenticationToken(
+ this.registeredClient.getClientId(), this.registeredClient.getClientSecret() + "-invalid");
+ assertThatThrownBy(() -> this.authenticationProvider.authenticate(authentication))
+ .isInstanceOf(OAuth2AuthenticationException.class)
+ .extracting(ex -> ((OAuth2AuthenticationException) ex).getError())
+ .extracting("errorCode")
+ .isEqualTo(OAuth2ErrorCodes.INVALID_CLIENT);
}
@Test
- public void authenticateWhenCredentialsNotEqualThenThrowOAuth2AuthorizationException() {
- assertThatThrownBy(() -> {
- this.authenticationProvider.authenticate(
- new OAuth2ClientAuthenticationToken(this.registeredClient.getClientId(),
- this.registeredClient.getClientSecret() + "_invalid"));
- }).isInstanceOf(OAuth2AuthenticationException.class);
- }
-
- @Test
- public void authenticateWhenAuthenticationSuccessResponseThenReturnClientAuthenticationToken() {
- OAuth2ClientAuthenticationToken authenticationResult = (OAuth2ClientAuthenticationToken) this.authenticationProvider.authenticate(
- new OAuth2ClientAuthenticationToken(this.registeredClient.getClientId(),
- registeredClient.getClientSecret()));
+ public void authenticateWhenValidCredentialsThenAuthenticated() {
+ OAuth2ClientAuthenticationToken authentication = new OAuth2ClientAuthenticationToken(
+ this.registeredClient.getClientId(), this.registeredClient.getClientSecret());
+ OAuth2ClientAuthenticationToken authenticationResult =
+ (OAuth2ClientAuthenticationToken) this.authenticationProvider.authenticate(authentication);
assertThat(authenticationResult.isAuthenticated()).isTrue();
- assertThat(authenticationResult.getAuthorities()).isEqualTo(Collections.emptyList());
+ assertThat(authenticationResult.getPrincipal().toString()).isEqualTo(this.registeredClient.getClientId());
+ assertThat(authenticationResult.getCredentials()).isNull();
+ assertThat(authenticationResult.getRegisteredClient()).isEqualTo(this.registeredClient);
}
}
diff --git a/core/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2ClientAuthenticationTokenTests.java b/core/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2ClientAuthenticationTokenTests.java
new file mode 100644
index 0000000..2147626
--- /dev/null
+++ b/core/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2ClientAuthenticationTokenTests.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2020 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.oauth2.server.authorization.authentication;
+
+import org.junit.Test;
+import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
+import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+/**
+ * Tests for {@link OAuth2ClientAuthenticationToken}.
+ *
+ * @author Joe Grandja
+ */
+public class OAuth2ClientAuthenticationTokenTests {
+
+ @Test
+ public void constructorWhenClientIdNullThenThrowIllegalArgumentException() {
+ assertThatThrownBy(() -> new OAuth2ClientAuthenticationToken(null, "secret"))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessage("clientId cannot be empty");
+ }
+
+ @Test
+ public void constructorWhenClientSecretNullThenThrowIllegalArgumentException() {
+ assertThatThrownBy(() -> new OAuth2ClientAuthenticationToken("clientId", null))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessage("clientSecret cannot be empty");
+ }
+
+ @Test
+ public void constructorWhenRegisteredClientNullThenThrowIllegalArgumentException() {
+ assertThatThrownBy(() -> new OAuth2ClientAuthenticationToken(null))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessage("registeredClient cannot be null");
+ }
+
+ @Test
+ public void constructorWhenClientCredentialsProvidedThenCreated() {
+ OAuth2ClientAuthenticationToken authentication = new OAuth2ClientAuthenticationToken("clientId", "secret");
+ assertThat(authentication.isAuthenticated()).isFalse();
+ assertThat(authentication.getPrincipal().toString()).isEqualTo("clientId");
+ assertThat(authentication.getCredentials()).isEqualTo("secret");
+ assertThat(authentication.getRegisteredClient()).isNull();
+ }
+
+ @Test
+ public void constructorWhenRegisteredClientProvidedThenCreated() {
+ RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build();
+ OAuth2ClientAuthenticationToken authentication = new OAuth2ClientAuthenticationToken(registeredClient);
+ assertThat(authentication.isAuthenticated()).isTrue();
+ assertThat(authentication.getPrincipal().toString()).isEqualTo(registeredClient.getClientId());
+ assertThat(authentication.getCredentials()).isNull();
+ assertThat(authentication.getRegisteredClient()).isEqualTo(registeredClient);
+ }
+}
diff --git a/core/src/test/java/org/springframework/security/oauth2/server/authorization/web/ClientSecretBasicAuthenticationConverterTests.java b/core/src/test/java/org/springframework/security/oauth2/server/authorization/web/ClientSecretBasicAuthenticationConverterTests.java
new file mode 100644
index 0000000..39e521e
--- /dev/null
+++ b/core/src/test/java/org/springframework/security/oauth2/server/authorization/web/ClientSecretBasicAuthenticationConverterTests.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2020 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.oauth2.server.authorization.web;
+
+import org.junit.Test;
+import org.springframework.http.HttpHeaders;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
+import org.springframework.security.oauth2.core.OAuth2ErrorCodes;
+import org.springframework.security.oauth2.server.authorization.authentication.OAuth2ClientAuthenticationToken;
+
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.util.Base64;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+/**
+ * Tests for {@link ClientSecretBasicAuthenticationConverter}.
+ *
+ * @author Patryk Kostrzewa
+ * @author Joe Grandja
+ */
+public class ClientSecretBasicAuthenticationConverterTests {
+ private ClientSecretBasicAuthenticationConverter converter = new ClientSecretBasicAuthenticationConverter();
+
+ @Test
+ public void convertWhenAuthorizationHeaderEmptyThenReturnNull() {
+ MockHttpServletRequest request = new MockHttpServletRequest();
+ Authentication authentication = this.converter.convert(request);
+ assertThat(authentication).isNull();
+ }
+
+ @Test
+ public void convertWhenAuthorizationHeaderNotBasicThenReturnNull() {
+ MockHttpServletRequest request = new MockHttpServletRequest();
+ request.addHeader(HttpHeaders.AUTHORIZATION, "Bearer token");
+ Authentication authentication = this.converter.convert(request);
+ assertThat(authentication).isNull();
+ }
+
+ @Test
+ public void convertWhenAuthorizationHeaderBasicWithMissingCredentialsThenThrowOAuth2AuthenticationException() {
+ MockHttpServletRequest request = new MockHttpServletRequest();
+ request.addHeader(HttpHeaders.AUTHORIZATION, "Basic ");
+ assertThatThrownBy(() -> this.converter.convert(request))
+ .isInstanceOf(OAuth2AuthenticationException.class)
+ .extracting(ex -> ((OAuth2AuthenticationException) ex).getError())
+ .extracting("errorCode")
+ .isEqualTo(OAuth2ErrorCodes.INVALID_REQUEST);
+ }
+
+ @Test
+ public void convertWhenAuthorizationHeaderBasicWithInvalidBase64ThenThrowOAuth2AuthenticationException() {
+ MockHttpServletRequest request = new MockHttpServletRequest();
+ request.addHeader(HttpHeaders.AUTHORIZATION, "Basic clientId:secret");
+ assertThatThrownBy(() -> this.converter.convert(request))
+ .isInstanceOf(OAuth2AuthenticationException.class)
+ .extracting(ex -> ((OAuth2AuthenticationException) ex).getError())
+ .extracting("errorCode")
+ .isEqualTo(OAuth2ErrorCodes.INVALID_REQUEST);
+ }
+
+ @Test
+ public void convertWhenAuthorizationHeaderBasicWithMissingSecretThenThrowOAuth2AuthenticationException() throws Exception {
+ MockHttpServletRequest request = new MockHttpServletRequest();
+ request.addHeader(HttpHeaders.AUTHORIZATION, "Basic " + encodeBasicAuth("clientId", ""));
+ assertThatThrownBy(() -> this.converter.convert(request))
+ .isInstanceOf(OAuth2AuthenticationException.class)
+ .extracting(ex -> ((OAuth2AuthenticationException) ex).getError())
+ .extracting("errorCode")
+ .isEqualTo(OAuth2ErrorCodes.INVALID_REQUEST);
+ }
+
+ @Test
+ public void convertWhenAuthorizationHeaderBasicWithValidCredentialsThenReturnClientAuthenticationToken() throws Exception {
+ MockHttpServletRequest request = new MockHttpServletRequest();
+ request.addHeader(HttpHeaders.AUTHORIZATION, "Basic " + encodeBasicAuth("clientId", "secret"));
+ OAuth2ClientAuthenticationToken authentication = (OAuth2ClientAuthenticationToken) this.converter.convert(request);
+ assertThat(authentication.getPrincipal()).isEqualTo("clientId");
+ assertThat(authentication.getCredentials()).isEqualTo("secret");
+ }
+
+ private static String encodeBasicAuth(String clientId, String secret) throws Exception {
+ clientId = URLEncoder.encode(clientId, StandardCharsets.UTF_8.name());
+ secret = URLEncoder.encode(secret, StandardCharsets.UTF_8.name());
+ String credentialsString = clientId + ":" + secret;
+ byte[] encodedBytes = Base64.getEncoder().encode(credentialsString.getBytes(StandardCharsets.UTF_8));
+ return new String(encodedBytes, StandardCharsets.UTF_8);
+ }
+}
diff --git a/core/src/test/java/org/springframework/security/oauth2/server/authorization/web/DefaultOAuth2ClientAuthenticationConverterTests.java b/core/src/test/java/org/springframework/security/oauth2/server/authorization/web/DefaultOAuth2ClientAuthenticationConverterTests.java
deleted file mode 100644
index 53fe560..0000000
--- a/core/src/test/java/org/springframework/security/oauth2/server/authorization/web/DefaultOAuth2ClientAuthenticationConverterTests.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright 2020 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.oauth2.server.authorization.web;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.springframework.http.HttpHeaders;
-import org.springframework.mock.web.MockHttpServletRequest;
-import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
-import org.springframework.security.oauth2.server.authorization.authentication.OAuth2ClientAuthenticationToken;
-import java.util.Base64;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-
-/**
- * Tests for {@link DefaultOAuth2ClientAuthenticationConverter}.
- *
- * @author Patryk Kostrzewa
- */
-public class DefaultOAuth2ClientAuthenticationConverterTests {
-
- private DefaultOAuth2ClientAuthenticationConverter converter;
-
- @Before
- public void setup() {
- this.converter = new DefaultOAuth2ClientAuthenticationConverter();
- }
-
- @Test
- public void convertWhenConversionSuccessThenReturnClientAuthenticationToken() {
- String token = "client:secret";
- MockHttpServletRequest request = new MockHttpServletRequest();
- request.addHeader(HttpHeaders.AUTHORIZATION, "Basic " + Base64.getEncoder()
- .encodeToString(token.getBytes()));
-
- OAuth2ClientAuthenticationToken authentication = this.converter.convert(request);
-
- assertThat(authentication).isNotNull();
- assertThat(authentication.getName()).isEqualTo("client");
- }
-
- @Test
- public void convertWithAuthorizationSchemeInMixedCaseWhenConversionSuccessThenReturnClientAuthenticationToken() {
- String token = "client:secret";
- MockHttpServletRequest request = new MockHttpServletRequest();
- request.addHeader(HttpHeaders.AUTHORIZATION, "BaSiC " + Base64.getEncoder()
- .encodeToString(token.getBytes()));
-
- final OAuth2ClientAuthenticationToken authentication = this.converter.convert(request);
-
- assertThat(authentication).isNotNull();
- assertThat(authentication.getName()).isEqualTo("client");
- }
-
- @Test
- public void convertWithIgnoringUnsupportedAuthenticationHeaderWhenConversionSuccessThenReturnClientAuthenticationToken() {
- MockHttpServletRequest request = new MockHttpServletRequest();
- request.addHeader(HttpHeaders.AUTHORIZATION, "Bearer unsupportedToken");
-
- OAuth2ClientAuthenticationToken authentication = this.converter.convert(request);
-
- assertThat(authentication).isNull();
- }
-
- @Test
- public void convertWhenNotValidTokenThenThrowOAuth2AuthenticationException() {
- MockHttpServletRequest request = new MockHttpServletRequest();
- request.addHeader(HttpHeaders.AUTHORIZATION, "Basic " + Base64.getEncoder()
- .encodeToString("client".getBytes()));
- assertThatThrownBy(() -> this.converter.convert(request)).isInstanceOf(OAuth2AuthenticationException.class);
- }
-
- @Test
- public void convertWhenNotValidBase64ThenThrowOAuth2AuthenticationException() {
- MockHttpServletRequest request = new MockHttpServletRequest();
- request.addHeader(HttpHeaders.AUTHORIZATION, "Basic NOT_VALID_BASE64");
- assertThatThrownBy(() -> this.converter.convert(request)).isInstanceOf(OAuth2AuthenticationException.class);
- }
-
- @Test
- public void convertWhenEmptyAuthenticationHeaderTokenThenThrowOAuth2AuthenticationException() {
- MockHttpServletRequest request = new MockHttpServletRequest();
- request.addHeader(HttpHeaders.AUTHORIZATION, "Basic ");
- assertThatThrownBy(() -> this.converter.convert(request)).isInstanceOf(OAuth2AuthenticationException.class);
- }
-}
diff --git a/core/src/test/java/org/springframework/security/oauth2/server/authorization/web/OAuth2ClientAuthenticationFilterTests.java b/core/src/test/java/org/springframework/security/oauth2/server/authorization/web/OAuth2ClientAuthenticationFilterTests.java
index eb99394..3d8d6fb 100644
--- a/core/src/test/java/org/springframework/security/oauth2/server/authorization/web/OAuth2ClientAuthenticationFilterTests.java
+++ b/core/src/test/java/org/springframework/security/oauth2/server/authorization/web/OAuth2ClientAuthenticationFilterTests.java
@@ -15,85 +15,197 @@
*/
package org.springframework.security.oauth2.server.authorization.web;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.mock.http.client.MockClientHttpResponse;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
+import org.springframework.security.oauth2.core.OAuth2Error;
+import org.springframework.security.oauth2.core.OAuth2ErrorCodes;
+import org.springframework.security.oauth2.core.http.converter.OAuth2ErrorHttpMessageConverter;
+import org.springframework.security.oauth2.server.authorization.authentication.OAuth2ClientAuthenticationToken;
+import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
+import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients;
+import org.springframework.security.web.authentication.AuthenticationConverter;
+import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;
+
import javax.servlet.FilterChain;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+
+import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoInteractions;
+import static org.mockito.Mockito.when;
/**
* Tests for {@link OAuth2ClientAuthenticationFilter}.
*
* @author Patryk Kostrzewa
+ * @author Joe Grandja
*/
public class OAuth2ClientAuthenticationFilterTests {
-
+ private String filterProcessesUrl = "/oauth2/token";
+ private AuthenticationManager authenticationManager;
+ private RequestMatcher requestMatcher;
+ private AuthenticationConverter authenticationConverter;
private OAuth2ClientAuthenticationFilter filter;
- private AuthenticationManager authenticationManager = mock(AuthenticationManager.class);
- private RequestMatcher requestMatcher = mock(RequestMatcher.class);
- private FilterChain filterChain = mock(FilterChain.class);
- private String filterProcessesUrl;
+ private final HttpMessageConverter