Repository: cxf Updated Branches: refs/heads/master 5f1a556bd -> 944bf866d
[CXF-5705] Some refactoring around client authentication support Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/944bf866 Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/944bf866 Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/944bf866 Branch: refs/heads/master Commit: 944bf866d181d19ec78b38b856a7c637a68e88af Parents: 5f1a556 Author: Sergey Beryozkin <[email protected]> Authored: Tue Apr 29 18:16:51 2014 +0100 Committer: Sergey Beryozkin <[email protected]> Committed: Tue Apr 29 18:16:51 2014 +0100 ---------------------------------------------------------------------- .../cxf/rs/security/oauth2/common/Client.java | 47 ++++------- .../oauth2/common/ClientCredential.java | 83 ++++++++++++++++++++ .../oauth2/common/ClientCredentialType.java | 25 ------ .../oauth2/services/AbstractTokenService.java | 21 ++--- .../oauth2/utils/ModelEncryptionSupport.java | 14 +++- .../oauth2/utils/EncryptionUtilsTest.java | 1 - .../security/oauth2/OAuthDataProviderImpl.java | 5 +- 7 files changed, 120 insertions(+), 76 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/944bf866/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 6ac8145..a6d81f2 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,8 +32,7 @@ public class Client implements Serializable { private static final long serialVersionUID = -5550840247125850922L; private String clientId; - private String clientCred; - private ClientCredentialType clientCredentialType = ClientCredentialType.PASSWORD; + private ClientCredential clientCred; private String applicationName; private String applicationDescription; @@ -55,7 +54,7 @@ public class Client implements Serializable { public Client(String clientId, String clientCred, boolean isConfidential) { this.clientId = clientId; - this.clientCred = clientCred; + this.clientCred = clientCred == null ? null : new ClientCredential(clientCred); this.isConfidential = isConfidential; } @@ -71,13 +70,15 @@ public class Client implements Serializable { } public Client(String clientId, - String clientCred, - ClientCredentialType clientCredType, + ClientCredential clientCred, boolean isConfidential, String applicationName, String applicationWebUri) { - this(clientId, clientCred, isConfidential, applicationName, applicationWebUri); - this.clientCredentialType = clientCredType; + this.clientId = clientId; + this.clientCred = clientCred; + this.isConfidential = isConfidential; + this.applicationName = applicationName; + this.applicationWebUri = applicationWebUri; } /** @@ -93,28 +94,16 @@ public class Client implements Serializable { } /** - * Gets the client secret - * @return the secret - */ - @Deprecated - public String getClientSecret() { - return clientCred; - } - - @Deprecated - public void setClientSecret(String secret) { - this.clientCred = secret; - } - - /** - * Gets the client credential - * @return the secret + * 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 */ - public String getClientCredential() { + public ClientCredential getClientCredential() { return clientCred; } - public void setClientCredential(String cred) { + public void setClientCredential(ClientCredential cred) { this.clientCred = cred; } @@ -302,12 +291,4 @@ public class Client implements Serializable { public void setRegisteredAudiences(List<String> registeredAudiences) { this.registeredAudiences = registeredAudiences; } - - public ClientCredentialType getClientCredentialType() { - return clientCredentialType; - } - - public void setClientCredentialType(ClientCredentialType clientCredentialType) { - this.clientCredentialType = clientCredentialType; - } } http://git-wip-us.apache.org/repos/asf/cxf/blob/944bf866/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/ClientCredential.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/ClientCredential.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/ClientCredential.java new file mode 100644 index 0000000..d21e84c --- /dev/null +++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/ClientCredential.java @@ -0,0 +1,83 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 + * + * http://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.apache.cxf.rs.security.oauth2.common; + +import java.io.Serializable; + +public class ClientCredential implements Serializable { + private static final long serialVersionUID = 6151645789585333184L; + public enum Type { + PASSWORD, + X509CERTIFICATE, + PUBLIC_KEY + } + + private String credential; + private Type type; + + public ClientCredential() { + + } + + public ClientCredential(String password) { + this(password, Type.PASSWORD); + } + + public ClientCredential(Type type) { + this(null, type); + } + + public ClientCredential(String cred, Type type) { + this.credential = cred; + this.type = type; + } + + public String getCredential() { + return credential; + } + + public void setCredential(String credential) { + this.credential = credential; + } + + public Type getType() { + return type; + } + + public void setType(Type type) { + this.type = type; + } + + public int hashCode() { + return (credential == null ? 37 : credential.hashCode()) * type.hashCode(); + } + public boolean equals(Object obj) { + if (obj instanceof ClientCredential) { + ClientCredential other = (ClientCredential)obj; + if (this.credential == null && other.credential != null + || this.credential != null && other.credential == null) { + return false; + } + return this.credential.equals(other.credential) && this.type.equals(other.type); + } else { + return false; + } + + } +} http://git-wip-us.apache.org/repos/asf/cxf/blob/944bf866/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/ClientCredentialType.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/ClientCredentialType.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/ClientCredentialType.java deleted file mode 100644 index 367b612..0000000 --- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/ClientCredentialType.java +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 - * - * http://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.apache.cxf.rs.security.oauth2.common; - -public enum ClientCredentialType { - PASSWORD, - X509CERTIFICATE, - PUBLIC_KEY -} http://git-wip-us.apache.org/repos/asf/cxf/blob/944bf866/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 f3068bf..9f2330a 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,7 @@ 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.ClientCredentialType; +import org.apache.cxf.rs.security.oauth2.common.ClientCredential; 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; @@ -100,8 +100,8 @@ public class AbstractTokenService extends AbstractOAuthService { protected Client getAndValidateClient(String clientId, String clientSecret) { Client client = getClient(clientId); if (clientSecret != null - && (client.getClientCredentialType() == null - || !ClientCredentialType.PASSWORD.equals(client.getClientCredentialType()))) { + && (client.getClientCredential().getType() == null + || ClientCredential.Type.PASSWORD != client.getClientCredential().getType())) { throw ExceptionUtils.toNotAuthorizedException(null, null); } if (canSupportPublicClients @@ -112,7 +112,7 @@ public class AbstractTokenService extends AbstractOAuthService { } if (clientSecret == null || client.getClientCredential() == null || !client.getClientId().equals(clientId) - || !client.getClientCredential().equals(clientSecret)) { + || !client.getClientCredential().getCredential().equals(clientSecret)) { throw ExceptionUtils.toNotAuthorizedException(null, null); } return client; @@ -158,23 +158,24 @@ public class AbstractTokenService extends AbstractOAuthService { } protected void validateTwoWayTlsClient(SecurityContext sc, TLSSessionInfo tlsSessionInfo, Client client) { - ClientCredentialType credType = client.getClientCredentialType(); - if (credType != ClientCredentialType.X509CERTIFICATE && credType != ClientCredentialType.PUBLIC_KEY) { + ClientCredential.Type credType = client.getClientCredential().getType(); + if (credType != ClientCredential.Type.X509CERTIFICATE + && credType != ClientCredential.Type.PUBLIC_KEY) { reportInvalidClient(); - } else if (client.getClientCredential() != null) { + } else if (client.getClientCredential().getCredential() != null) { // Client has a Base64 encoded representation of the certificate loaded // so lets validate the TLS certificates - compareCertificates(tlsSessionInfo, client.getClientCredential(), credType); + compareCertificates(tlsSessionInfo, client.getClientCredential().getCredential(), credType); } } protected void compareCertificates(TLSSessionInfo tlsInfo, String base64EncodedCert, - ClientCredentialType type) { + ClientCredential.Type type) { Certificate[] clientCerts = tlsInfo.getPeerCertificates(); try { X509Certificate cert = (X509Certificate)clientCerts[0]; - byte[] encodedKey = type == ClientCredentialType.PUBLIC_KEY + byte[] encodedKey = type == ClientCredential.Type.PUBLIC_KEY ? cert.getPublicKey().getEncoded() : cert.getEncoded(); byte[] clientKey = Base64Utility.decode(base64EncodedCert); if (Arrays.equals(encodedKey, clientKey)) { http://git-wip-us.apache.org/repos/asf/cxf/blob/944bf866/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 a6dd2bb..5d4a98d 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,8 +29,9 @@ 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.ClientCredentialType; +import org.apache.cxf.rs.security.oauth2.common.ClientCredential; 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; @@ -323,7 +324,11 @@ public final class ModelEncryptionSupport { private static Client recreateClientInternal(String sequence) { String[] parts = getParts(sequence); - Client c = new Client(parts[0], parts[1], ClientCredentialType.valueOf(parts[2]), + ClientCredential clientCred = StringUtils.isEmpty(parts[1]) + ? null : new ClientCredential(parts[1], + ClientCredential.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])); @@ -341,11 +346,12 @@ public final class ModelEncryptionSupport { // 0: id state.append(tokenizeString(client.getClientId())); state.append(SEP); + ClientCredential cred = client.getClientCredential(); // 1: secret - state.append(tokenizeString(client.getClientCredential())); + state.append(tokenizeString(cred == null ? null : cred.getCredential())); state.append(SEP); // 1.1: secret type - state.append(tokenizeString(client.getClientCredentialType().toString())); + state.append(tokenizeString(cred == null ? null : cred.getType().toString())); state.append(SEP); // 2: confidentiality state.append(client.isConfidential()); http://git-wip-us.apache.org/repos/asf/cxf/blob/944bf866/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 47a2f80..26f3100 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 @@ -170,7 +170,6 @@ public class EncryptionUtilsTest extends Assert { ByteArrayOutputStream bos = new ByteArrayOutputStream(); jsonp.writeTo(c, Client.class, new Annotation[]{}, MediaType.APPLICATION_JSON_TYPE, new MetadataMap<String, Object>(), bos); - String encrypted = EncryptionUtils.encryptSequence(bos.toString(), p.key); String decrypted = EncryptionUtils.decryptSequence(encrypted, p.key); Client c2 = jsonp.readFrom(Client.class, Client.class, http://git-wip-us.apache.org/repos/asf/cxf/blob/944bf866/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 460129a..3ec9f2b 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,7 @@ 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.ClientCredentialType; +import org.apache.cxf.rs.security.oauth2.common.ClientCredential; 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,8 +45,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", - null, - ClientCredentialType.X509CERTIFICATE, + new ClientCredential(ClientCredential.Type.X509CERTIFICATE), true, null, null);
