This is an automated email from the ASF dual-hosted git repository. coheigea pushed a commit to branch 3.2.x-fixes in repository https://gitbox.apache.org/repos/asf/cxf.git
commit db6069667708a59c75a785f310d4a2df3698122c Author: Colm O hEigeartaigh <cohei...@apache.org> AuthorDate: Wed Sep 11 00:43:48 2019 +0100 Make sure that the OAuth authenticate principal name matches the client_id (if specified) (cherry picked from commit 337609d81a9f53e7680cb79d9ab733a79f4cd769) (cherry picked from commit 6bf89927d3e07197d49453b00d673eadce696cf9) --- .../oauth2/services/AbstractTokenService.java | 25 +++-- .../grants/AuthorizationGrantNegativeTest.java | 123 +++++++++++++++++++++ .../oauth2/grants/AuthorizationGrantTest.java | 4 +- 3 files changed, 138 insertions(+), 14 deletions(-) diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/AbstractTokenService.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/AbstractTokenService.java index a5e82a2..8e32cca 100644 --- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/AbstractTokenService.java +++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/AbstractTokenService.java @@ -56,8 +56,8 @@ public class AbstractTokenService extends AbstractOAuthService { SecurityContext sc = getMessageContext().getSecurityContext(); Principal principal = sc.getUserPrincipal(); + String clientId = retrieveClientId(params); if (principal == null) { - String clientId = retrieveClientId(params); if (clientId != null) { String clientSecret = params.getFirst(OAuthConstants.CLIENT_SECRET); if (clientSecret != null) { @@ -77,11 +77,12 @@ public class AbstractTokenService extends AbstractOAuthService { } } } else { - String clientId = retrieveClientId(params); if (clientId != null) { - if (clientId.equals(principal.getName())) { - client = (Client)getMessageContext().get(Client.class.getName()); + if (!clientId.equals(principal.getName())) { + reportInvalidClient(); } + + client = (Client)getMessageContext().get(Client.class.getName()); if (client == null) { client = getClient(clientId, params); } @@ -108,7 +109,7 @@ public class AbstractTokenService extends AbstractOAuthService { reportInvalidClient(new OAuthError(OAuthConstants.UNAUTHORIZED_CLIENT)); } } - + protected String retrieveClientId(MultivaluedMap<String, String> params) { String clientId = params.getFirst(OAuthConstants.CLIENT_ID); if (clientId == null) { @@ -164,14 +165,14 @@ public class AbstractTokenService extends AbstractOAuthService { reportInvalidClient(); } X509Certificate cert = OAuthUtils.getRootTLSCertificate(tlsSessionInfo); - - if (subjectDn != null + + if (subjectDn != null && !subjectDn.equals(OAuthUtils.getSubjectDnFromTLSCertificates(cert))) { LOG.warning("Client \"" + client.getClientId() + "\" can not be bound to the TLS certificate"); reportInvalidClient(); } String issuerDn = client.getProperties().get(OAuthConstants.TLS_CLIENT_AUTH_ISSUER_DN); - if (issuerDn != null + if (issuerDn != null && !issuerDn.equals(OAuthUtils.getIssuerDnFromTLSCertificates(cert))) { LOG.warning("Client \"" + client.getClientId() + "\" can not be bound to the TLS certificate"); reportInvalidClient(); @@ -187,7 +188,7 @@ public class AbstractTokenService extends AbstractOAuthService { return (TLSSessionInfo)getMessageContext().get(TLSSessionInfo.class.getName()); } - + protected Client getClientFromTLSCertificates(SecurityContext sc, TLSSessionInfo tlsSessionInfo, MultivaluedMap<String, String> params) { @@ -206,11 +207,11 @@ public class AbstractTokenService extends AbstractOAuthService { } return client; } - + protected void compareTlsCertificates(TLSSessionInfo tlsInfo, List<String> base64EncodedCerts) { if (!OAuthUtils.compareTlsCertificates(tlsInfo, base64EncodedCerts)) { - reportInvalidClient(); + reportInvalidClient(); } } @@ -244,7 +245,7 @@ public class AbstractTokenService extends AbstractOAuthService { protected Client getClient(String clientId, MultivaluedMap<String, String> params) { return getClient(clientId, params.getFirst(OAuthConstants.CLIENT_SECRET), params); } - + protected Client getClient(String clientId, String clientSecret, MultivaluedMap<String, String> params) { if (clientId == null) { reportInvalidRequestError("Client ID is null"); diff --git a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/grants/AuthorizationGrantNegativeTest.java b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/grants/AuthorizationGrantNegativeTest.java index 66e8739..752071e 100644 --- a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/grants/AuthorizationGrantNegativeTest.java +++ b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/grants/AuthorizationGrantNegativeTest.java @@ -555,6 +555,129 @@ public class AuthorizationGrantNegativeTest extends AbstractBusClientServerTestB } } + // Here we are sending a different client Id in both the authz + token requests + @org.junit.Test + public void testNonMatchingClientId() throws Exception { + URL busFile = AuthorizationGrantTest.class.getResource("client.xml"); + + String address = "https://localhost:" + port + "/services/"; + WebClient client = WebClient.create(address, OAuth2TestUtils.setupProviders(), + "alice", "security", busFile.toString()); + // Save the Cookie for the second request... + WebClient.getConfig(client).getRequestContext().put( + org.apache.cxf.message.Message.MAINTAIN_SESSION, Boolean.TRUE); + + // Get Authorization Code + String code = OAuth2TestUtils.getAuthorizationCode(client); + assertNotNull(code); + + // Now get the access token using a different client id + client = WebClient.create(address, OAuth2TestUtils.setupProviders(), + "consumer-id-aud", "this-is-a-secret", busFile.toString()); + // Save the Cookie for the second request... + WebClient.getConfig(client).getRequestContext().put( + org.apache.cxf.message.Message.MAINTAIN_SESSION, Boolean.TRUE); + + client.type("application/x-www-form-urlencoded").accept("application/json"); + client.path("token"); + + Form form = new Form(); + form.param("grant_type", "authorization_code"); + form.param("code", code); + form.param("client_id", "consumer-id-aud"); + + // Now try to get a token + Response response = client.post(form); + try { + response.readEntity(ClientAccessToken.class); + fail("Failure expected on trying to get a token"); + } catch (ResponseProcessingException ex) { + //expected + } + } + + // Here we are sending a different client Id in both the authz + token requests + @org.junit.Test + public void testNonMatchingClientIdBasicAuth() throws Exception { + URL busFile = AuthorizationGrantTest.class.getResource("client.xml"); + + String address = "https://localhost:" + port + "/services/"; + WebClient client = WebClient.create(address, OAuth2TestUtils.setupProviders(), + "alice", "security", busFile.toString()); + // Save the Cookie for the second request... + WebClient.getConfig(client).getRequestContext().put( + org.apache.cxf.message.Message.MAINTAIN_SESSION, Boolean.TRUE); + + // Get Authorization Code + String code = OAuth2TestUtils.getAuthorizationCode(client); + assertNotNull(code); + + // Now get the access token using a different client id + client = WebClient.create(address, OAuth2TestUtils.setupProviders(), + "consumer-id-aud", "this-is-a-secret", busFile.toString()); + // Save the Cookie for the second request... + WebClient.getConfig(client).getRequestContext().put( + org.apache.cxf.message.Message.MAINTAIN_SESSION, Boolean.TRUE); + + client.type("application/x-www-form-urlencoded").accept("application/json"); + client.path("token"); + + Form form = new Form(); + form.param("grant_type", "authorization_code"); + form.param("code", code); + + // Now try to get a token + Response response = client.post(form); + try { + response.readEntity(ClientAccessToken.class); + fail("Failure expected on trying to get a token"); + } catch (ResponseProcessingException ex) { + //expected + } + } + + // Here we are sending a different client Id in both the authz + token requests, where in the + // token request we authenticate using a different clientId + @org.junit.Test + public void testNonMatchingClientDifferentClientIds() throws Exception { + URL busFile = AuthorizationGrantTest.class.getResource("client.xml"); + + String address = "https://localhost:" + port + "/services/"; + WebClient client = WebClient.create(address, OAuth2TestUtils.setupProviders(), + "alice", "security", busFile.toString()); + // Save the Cookie for the second request... + WebClient.getConfig(client).getRequestContext().put( + org.apache.cxf.message.Message.MAINTAIN_SESSION, Boolean.TRUE); + + // Get Authorization Code + String code = OAuth2TestUtils.getAuthorizationCode(client); + assertNotNull(code); + + // Now get the access token using a different client id + client = WebClient.create(address, OAuth2TestUtils.setupProviders(), + "consumer-id-aud", "this-is-a-secret", busFile.toString()); + // Save the Cookie for the second request... + WebClient.getConfig(client).getRequestContext().put( + org.apache.cxf.message.Message.MAINTAIN_SESSION, Boolean.TRUE); + + client.type("application/x-www-form-urlencoded").accept("application/json"); + client.path("token"); + + Form form = new Form(); + form.param("grant_type", "authorization_code"); + form.param("code", code); + form.param("client_id", "consumer-id"); + + // Now try to get a token + Response response = client.post(form); + try { + response.readEntity(ClientAccessToken.class); + fail("Failure expected on trying to get a token"); + } catch (ResponseProcessingException ex) { + //expected + } + } + // // SAML Authorization grants // diff --git a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/grants/AuthorizationGrantTest.java b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/grants/AuthorizationGrantTest.java index a8c06ed..f59a15b 100644 --- a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/grants/AuthorizationGrantTest.java +++ b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/grants/AuthorizationGrantTest.java @@ -495,7 +495,7 @@ public class AuthorizationGrantTest extends AbstractBusClientServerTestBase { String address = "https://localhost:" + port + "/services/"; WebClient client = WebClient.create(address, OAuth2TestUtils.setupProviders(), - "alice", "security", busFile.toString()); + "consumer-id", "this-is-a-secret", busFile.toString()); // Create the SAML Assertion String assertion = OAuth2TestUtils.createToken(address + "token"); @@ -525,7 +525,7 @@ public class AuthorizationGrantTest extends AbstractBusClientServerTestBase { String address = "https://localhost:" + port + "/services/"; WebClient client = WebClient.create(address, OAuth2TestUtils.setupProviders(), - "alice", "security", busFile.toString()); + "consumer-id", "this-is-a-secret", busFile.toString()); // Create the JWT Token String token = OAuth2TestUtils.createToken("DoubleItSTSIssuer", "consumer-id",