[CXF-5705] Removing ClientKey after all
Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/338c66a5 Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/338c66a5 Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/338c66a5 Branch: refs/heads/master Commit: 338c66a5a3ec9fa76cbcf707eaadeff7117cc9b2 Parents: a7674fd Author: Sergey Beryozkin <[email protected]> Authored: Wed Apr 30 14:23:03 2014 +0100 Committer: Sergey Beryozkin <[email protected]> Committed: Wed Apr 30 14:23:03 2014 +0100 ---------------------------------------------------------------------- .../cxf/rs/security/oauth2/common/Client.java | 52 +++++++------- .../oauth2/services/AbstractTokenService.java | 74 +++++++------------- .../services/AuthorizationCodeGrantService.java | 2 +- .../oauth2/utils/ModelEncryptionSupport.java | 32 ++++----- .../oauth2/utils/EncryptionUtilsTest.java | 2 +- .../security/oauth2/OAuthDataProviderImpl.java | 3 +- 6 files changed, 69 insertions(+), 96 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/338c66a5/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/Client.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/Client.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/Client.java index f58d38c..88a3c4a 100644 --- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/Client.java +++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/Client.java @@ -32,12 +32,13 @@ public class Client implements Serializable { private static final long serialVersionUID = -5550840247125850922L; private String clientId; - private ClientKey clientKey; + private String clientSecret; private String applicationName; private String applicationDescription; private String applicationWebUri; private String applicationLogoUri; + private String applicationCertificate; private List<String> redirectUris = new LinkedList<String>(); private boolean isConfidential; @@ -54,7 +55,7 @@ public class Client implements Serializable { public Client(String clientId, String clientSecret, boolean isConfidential) { this.clientId = clientId; - this.clientKey = clientSecret == null ? null : new ClientKey(clientSecret); + this.clientSecret = clientSecret; this.isConfidential = isConfidential; } @@ -69,20 +70,8 @@ public class Client implements Serializable { } - public Client(String clientId, - ClientKey clientKey, - boolean isConfidential, - String applicationName, - String applicationWebUri) { - this.clientId = clientId; - this.clientKey = clientKey; - this.isConfidential = isConfidential; - this.applicationName = applicationName; - this.applicationWebUri = applicationWebUri; - } - /** - * Gets the client registration id + * Get the client registration id * @return the consumer key */ public String getClientId() { @@ -94,19 +83,17 @@ public class Client implements Serializable { } /** - * Get the client credential. - * If it is a certificate or public key and not null then - * it has to be a Base64 encoded representation - * @return the credential + * Get the client secret + * @return the consumer key */ - public ClientKey getClientKey() { - return clientKey; + public String getClientSecret() { + return clientSecret; } - public void setClientKey(ClientKey key) { - this.clientKey = key; + public void setClientSecret(String id) { + clientSecret = id; } - + /** * Gets the name of the third-party application * this client represents @@ -288,7 +275,24 @@ public class Client implements Serializable { return registeredAudiences; } + /** + * Set the list of registered audiences + * @param registeredAudiences audiences + */ public void setRegisteredAudiences(List<String> registeredAudiences) { this.registeredAudiences = registeredAudiences; } + + public String getApplicationCertificate() { + return applicationCertificate; + } + + /* + * Set the optional Base64 encoded Application Public X509 Certificate + * It can be used in combination with the clientSecret property to support + * Basic or other password-aware authentication on top of 2-way TLS. + */ + public void setApplicationCertificate(String applicationCertificate) { + this.applicationCertificate = applicationCertificate; + } } http://git-wip-us.apache.org/repos/asf/cxf/blob/338c66a5/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/AbstractTokenService.java ---------------------------------------------------------------------- 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 c3b9fef..6f6594a 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 @@ -36,7 +36,6 @@ import org.apache.cxf.common.util.StringUtils; import org.apache.cxf.jaxrs.utils.ExceptionUtils; import org.apache.cxf.jaxrs.utils.JAXRSUtils; import org.apache.cxf.rs.security.oauth2.common.Client; -import org.apache.cxf.rs.security.oauth2.common.ClientKey; import org.apache.cxf.rs.security.oauth2.common.OAuthError; import org.apache.cxf.rs.security.oauth2.provider.ClientIdProvider; import org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException; @@ -82,12 +81,15 @@ public class AbstractTokenService extends AbstractOAuthService { if (client == null) { TLSSessionInfo tlsSessionInfo = (TLSSessionInfo)getMessageContext().get(TLSSessionInfo.class.getName()); - if (tlsSessionInfo != null) { - client = getClientFromTLSCertificates(sc, tlsSessionInfo); - } else { + client = getClientFromTLSCertificates(sc, tlsSessionInfo); + if (client == null) { // Basic Authentication is expected by default client = getClientFromBasicAuthScheme(); } + if (client != null && tlsSessionInfo != null) { + // Validate the client application certificates + compareTlsCertificates(tlsSessionInfo, client.getApplicationCertificate()); + } } if (client == null) { @@ -99,20 +101,15 @@ public class AbstractTokenService extends AbstractOAuthService { // Get the Client and check the id and secret protected Client getAndValidateClientFromIdAndSecret(String clientId, String clientSecret) { Client client = getClient(clientId); - if (clientSecret != null - && (client.getClientKey().getType() == null - || ClientKey.Type.PASSWORD != client.getClientKey().getType())) { - throw ExceptionUtils.toNotAuthorizedException(null, null); - } if (canSupportPublicClients && !client.isConfidential() - && client.getClientKey() == null + && client.getClientSecret() == null && clientSecret == null) { return client; } - if (clientSecret == null || client.getClientKey() == null + if (clientSecret == null || client.getClientSecret() == null || !client.getClientId().equals(clientId) - || !client.getClientKey().getKey().equals(clientSecret)) { + || !client.getClientSecret().equals(clientSecret)) { throw ExceptionUtils.toNotAuthorizedException(null, null); } return client; @@ -130,19 +127,11 @@ public class AbstractTokenService extends AbstractOAuthService { protected Client getClientFromTLSCertificates(SecurityContext sc, TLSSessionInfo tlsSessionInfo) { Client client = null; - if (tlsSessionInfo != null) { - String authScheme = sc.getAuthenticationScheme(); - if (StringUtils.isEmpty(authScheme)) { - // Pure 2-way TLS authentication - String clientId = getClientIdFromTLSCertificates(sc, tlsSessionInfo); - if (!StringUtils.isEmpty(clientId)) { - client = getClient(clientId); - // Validate the client identified from certificates - validateTwoWayTlsClient(sc, tlsSessionInfo, client); - } - } else if (OAuthConstants.BASIC_SCHEME.equalsIgnoreCase(authScheme)) { - // Basic Authentication on top of 2-way TLS - client = getClientFromBasicAuthScheme(); + if (tlsSessionInfo != null && StringUtils.isEmpty(sc.getAuthenticationScheme())) { + // Pure 2-way TLS authentication + String clientId = getClientIdFromTLSCertificates(sc, tlsSessionInfo); + if (!StringUtils.isEmpty(clientId)) { + client = getClient(clientId); } } return client; @@ -157,30 +146,19 @@ public class AbstractTokenService extends AbstractOAuthService { return null; } - protected void validateTwoWayTlsClient(SecurityContext sc, TLSSessionInfo tlsSessionInfo, Client client) { - ClientKey.Type credType = client.getClientKey().getType(); - if (credType != ClientKey.Type.X509CERTIFICATE) { - reportInvalidClient(); - } else if (client.getClientKey().getKey() != null) { - // Client has a Base64 encoded representation of the certificate loaded - // so lets validate the TLS certificates - compareCertificates(tlsSessionInfo, client.getClientKey().getKey(), credType); - } - } - - protected void compareCertificates(TLSSessionInfo tlsInfo, - String base64EncodedCert, - ClientKey.Type type) { - Certificate[] clientCerts = tlsInfo.getPeerCertificates(); - try { - X509Certificate cert = (X509Certificate)clientCerts[0]; - byte[] encodedKey = cert.getEncoded(); - byte[] clientKey = Base64Utility.decode(base64EncodedCert); - if (Arrays.equals(encodedKey, clientKey)) { - return; + protected void compareTlsCertificates(TLSSessionInfo tlsInfo, String base64EncodedCert) { + if (tlsInfo != null && base64EncodedCert != null) { + Certificate[] clientCerts = tlsInfo.getPeerCertificates(); + try { + X509Certificate cert = (X509Certificate)clientCerts[0]; + byte[] encodedKey = cert.getEncoded(); + byte[] clientKey = Base64Utility.decode(base64EncodedCert); + if (Arrays.equals(encodedKey, clientKey)) { + return; + } + } catch (Exception ex) { + reportInvalidClient(); } - } catch (Exception ex) { - reportInvalidClient(); } } http://git-wip-us.apache.org/repos/asf/cxf/blob/338c66a5/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/AuthorizationCodeGrantService.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/AuthorizationCodeGrantService.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/AuthorizationCodeGrantService.java index ed3fa46..a4b48ce 100644 --- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/AuthorizationCodeGrantService.java +++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/AuthorizationCodeGrantService.java @@ -126,7 +126,7 @@ public class AuthorizationCodeGrantService extends RedirectionBasedGrantService @Override protected boolean canSupportPublicClient(Client c) { - return canSupportPublicClients && !c.isConfidential() && c.getClientKey() == null; + return canSupportPublicClients && !c.isConfidential() && c.getClientSecret() == null; } @Override http://git-wip-us.apache.org/repos/asf/cxf/blob/338c66a5/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/ModelEncryptionSupport.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/ModelEncryptionSupport.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/ModelEncryptionSupport.java index 14f764d..f641ad9 100644 --- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/ModelEncryptionSupport.java +++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/ModelEncryptionSupport.java @@ -29,9 +29,7 @@ import java.util.Map; import javax.crypto.SecretKey; -import org.apache.cxf.common.util.StringUtils; import org.apache.cxf.rs.security.oauth2.common.Client; -import org.apache.cxf.rs.security.oauth2.common.ClientKey; import org.apache.cxf.rs.security.oauth2.common.OAuthPermission; import org.apache.cxf.rs.security.oauth2.common.ServerAccessToken; import org.apache.cxf.rs.security.oauth2.common.UserSubject; @@ -324,20 +322,18 @@ public final class ModelEncryptionSupport { private static Client recreateClientInternal(String sequence) { String[] parts = getParts(sequence); - ClientKey clientCred = StringUtils.isEmpty(parts[1]) ? null - : new ClientKey(parts[1], ClientKey.Type.valueOf(parts[2])); Client c = new Client(parts[0], - clientCred, - Boolean.valueOf(parts[3]), - getStringPart(parts[4]), getStringPart(parts[5])); - c.setApplicationDescription(getStringPart(parts[6])); - c.setApplicationLogoUri(getStringPart(parts[7])); - c.setAllowedGrantTypes(parseSimpleList(parts[8])); - c.setRegisteredScopes(parseSimpleList(parts[9])); - c.setRedirectUris(parseSimpleList(parts[10])); - c.setRegisteredAudiences(parseSimpleList(parts[11])); - c.setProperties(parseSimpleMap(parts[12])); - c.setSubject(recreateUserSubject(parts[13])); + parts[1], + Boolean.valueOf(parts[2]), + getStringPart(parts[3]), getStringPart(parts[4])); + c.setApplicationDescription(getStringPart(parts[5])); + c.setApplicationLogoUri(getStringPart(parts[6])); + c.setAllowedGrantTypes(parseSimpleList(parts[7])); + c.setRegisteredScopes(parseSimpleList(parts[8])); + c.setRedirectUris(parseSimpleList(parts[9])); + c.setRegisteredAudiences(parseSimpleList(parts[10])); + c.setProperties(parseSimpleMap(parts[11])); + c.setSubject(recreateUserSubject(parts[12])); return c; } private static String tokenizeClient(Client client) { @@ -345,12 +341,8 @@ public final class ModelEncryptionSupport { // 0: id state.append(tokenizeString(client.getClientId())); state.append(SEP); - ClientKey cred = client.getClientKey(); // 1: secret - state.append(tokenizeString(cred == null ? null : cred.getKey())); - state.append(SEP); - // 1.1: secret type - state.append(tokenizeString(cred == null ? null : cred.getType().toString())); + state.append(tokenizeString(client.getClientSecret())); state.append(SEP); // 2: confidentiality state.append(client.isConfidential()); http://git-wip-us.apache.org/repos/asf/cxf/blob/338c66a5/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/utils/EncryptionUtilsTest.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/utils/EncryptionUtilsTest.java b/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/utils/EncryptionUtilsTest.java index ef44818..7f153e5 100644 --- a/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/utils/EncryptionUtilsTest.java +++ b/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/utils/EncryptionUtilsTest.java @@ -178,7 +178,7 @@ public class EncryptionUtilsTest extends Assert { new ByteArrayInputStream(decrypted.getBytes())); assertEquals(c.getClientId(), c2.getClientId()); - assertEquals(c.getClientKey(), c2.getClientKey()); + assertEquals(c.getClientSecret(), c2.getClientSecret()); assertTrue(c2.isConfidential()); assertEquals("subject", c2.getSubject().getLogin()); assertEquals("id", c2.getSubject().getId()); http://git-wip-us.apache.org/repos/asf/cxf/blob/338c66a5/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/OAuthDataProviderImpl.java ---------------------------------------------------------------------- diff --git a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/OAuthDataProviderImpl.java b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/OAuthDataProviderImpl.java index ebbe428..54917f4 100644 --- a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/OAuthDataProviderImpl.java +++ b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/OAuthDataProviderImpl.java @@ -24,7 +24,6 @@ import java.util.Map; import org.apache.cxf.rs.security.oauth2.common.AccessTokenRegistration; import org.apache.cxf.rs.security.oauth2.common.Client; -import org.apache.cxf.rs.security.oauth2.common.ClientKey; import org.apache.cxf.rs.security.oauth2.common.OAuthPermission; import org.apache.cxf.rs.security.oauth2.common.ServerAccessToken; import org.apache.cxf.rs.security.oauth2.common.UserSubject; @@ -45,7 +44,7 @@ public class OAuthDataProviderImpl implements OAuthDataProvider { clients.put(client.getClientId(), client); Client client2 = new Client("CN=whateverhost.com,OU=Morpit,O=ApacheTest,L=Syracuse,C=US", - new ClientKey(ClientKey.Type.X509CERTIFICATE), + null, true, null, null);
