You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by se...@apache.org on 2014/04/29 18:10:22 UTC
git commit: [CXF-5705] Better support for the client authentication,
including 2-way TLS
Repository: cxf
Updated Branches:
refs/heads/master e2eacb217 -> 5f1a556bd
[CXF-5705] Better support for the client authentication, including 2-way TLS
Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/5f1a556b
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/5f1a556b
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/5f1a556b
Branch: refs/heads/master
Commit: 5f1a556bda9d4eb50c3dae1de2b0408ae461ea99
Parents: e2eacb2
Author: Sergey Beryozkin <sb...@talend.com>
Authored: Tue Apr 29 17:10:01 2014 +0100
Committer: Sergey Beryozkin <sb...@talend.com>
Committed: Tue Apr 29 17:10:01 2014 +0100
----------------------------------------------------------------------
.../cxf/rs/security/oauth2/common/Client.java | 49 +++++--
.../oauth2/common/ClientCredentialType.java | 25 ++++
.../oauth2/provider/ClientIdProvider.java | 37 +++++
.../oauth2/services/AbstractTokenService.java | 138 +++++++++++++++----
.../services/AuthorizationCodeGrantService.java | 2 +-
.../oauth2/utils/ModelEncryptionSupport.java | 27 ++--
.../oauth2/utils/EncryptionUtilsTest.java | 2 +-
.../jaxrs/security/oauth2/JAXRSOAuth2Test.java | 9 ++
.../security/oauth2/OAuthDataProviderImpl.java | 24 +++-
9 files changed, 263 insertions(+), 50 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cxf/blob/5f1a556b/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 ba0e20b..6ac8145 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,9 +32,8 @@ public class Client implements Serializable {
private static final long serialVersionUID = -5550840247125850922L;
private String clientId;
- // TODO: Consider introducing ClientCredentials instead
- // so that a secret, public key, etc can be kept
- private String clientSecret;
+ private String clientCred;
+ private ClientCredentialType clientCredentialType = ClientCredentialType.PASSWORD;
private String applicationName;
private String applicationDescription;
@@ -54,23 +53,33 @@ public class Client implements Serializable {
}
- public Client(String clientId, String clientSecret, boolean isConfidential) {
+ public Client(String clientId, String clientCred, boolean isConfidential) {
this.clientId = clientId;
- this.clientSecret = clientSecret;
+ this.clientCred = clientCred;
this.isConfidential = isConfidential;
}
public Client(String clientId,
- String clientSecret,
+ String clientCred,
boolean isConfidential,
String applicationName,
String applicationWebUri) {
- this(clientId, clientSecret, isConfidential);
+ this(clientId, clientCred, isConfidential);
this.applicationName = applicationName;
this.applicationWebUri = applicationWebUri;
}
+ public Client(String clientId,
+ String clientCred,
+ ClientCredentialType clientCredType,
+ boolean isConfidential,
+ String applicationName,
+ String applicationWebUri) {
+ this(clientId, clientCred, isConfidential, applicationName, applicationWebUri);
+ this.clientCredentialType = clientCredType;
+ }
+
/**
* Gets the client registration id
* @return the consumer key
@@ -87,12 +96,26 @@ public class Client implements Serializable {
* Gets the client secret
* @return the secret
*/
+ @Deprecated
public String getClientSecret() {
- return clientSecret;
+ return clientCred;
}
+ @Deprecated
public void setClientSecret(String secret) {
- this.clientSecret = secret;
+ this.clientCred = secret;
+ }
+
+ /**
+ * Gets the client credential
+ * @return the secret
+ */
+ public String getClientCredential() {
+ return clientCred;
+ }
+
+ public void setClientCredential(String cred) {
+ this.clientCred = cred;
}
/**
@@ -279,4 +302,12 @@ 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/5f1a556b/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
new file mode 100644
index 0000000..367b612
--- /dev/null
+++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/ClientCredentialType.java
@@ -0,0 +1,25 @@
+/**
+ * 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/5f1a556b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/ClientIdProvider.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/ClientIdProvider.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/ClientIdProvider.java
new file mode 100644
index 0000000..f0b9a7a
--- /dev/null
+++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/ClientIdProvider.java
@@ -0,0 +1,37 @@
+/**
+ * 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.provider;
+
+import org.apache.cxf.jaxrs.ext.MessageContext;
+
+/**
+ * ClientIdProvider responsible for providing a mapping between
+ * the authenticated client and its id
+ */
+public interface ClientIdProvider {
+
+ /**
+ * Get a client id
+ *
+ * @param mc the {@link MessageContext} of this request
+ * @return the client id
+ */
+ String getClientId(MessageContext mc);
+}
http://git-wip-us.apache.org/repos/asf/cxf/blob/5f1a556b/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 0ef9008..f3068bf 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
@@ -20,24 +20,34 @@
package org.apache.cxf.rs.security.oauth2.services;
import java.security.Principal;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import javax.security.auth.x500.X500Principal;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.SecurityContext;
+import org.apache.cxf.common.util.Base64Utility;
+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.OAuthError;
+import org.apache.cxf.rs.security.oauth2.provider.ClientIdProvider;
import org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException;
import org.apache.cxf.rs.security.oauth2.utils.AuthorizationUtils;
import org.apache.cxf.rs.security.oauth2.utils.OAuthConstants;
+import org.apache.cxf.security.transport.TLSSessionInfo;
public class AbstractTokenService extends AbstractOAuthService {
private boolean canSupportPublicClients;
private boolean writeCustomErrors;
+ private ClientIdProvider clientIdProvider;
/**
* Make sure the client is authenticated
@@ -47,36 +57,36 @@ public class AbstractTokenService extends AbstractOAuthService {
SecurityContext sc = getMessageContext().getSecurityContext();
if (params.containsKey(OAuthConstants.CLIENT_ID)) {
- // both client_id and client_secret are expected in the form payload
+ // Both client_id and client_secret are expected in the form payload
client = getAndValidateClient(params.getFirst(OAuthConstants.CLIENT_ID),
params.getFirst(OAuthConstants.CLIENT_SECRET));
} else if (sc.getUserPrincipal() != null) {
- // client has already authenticated
+ // Client has already been authenticated
Principal p = sc.getUserPrincipal();
- String scheme = sc.getAuthenticationScheme();
- if (OAuthConstants.BASIC_SCHEME.equalsIgnoreCase(scheme)) {
- // section 2.3.1
+ if (p.getName() != null) {
client = getClient(p.getName());
} else {
- // section 2.3.2
- // the client has authenticated itself using some other scheme
- // in which case the mapping between the scheme and the client_id
- // should've been done and the client_id is expected
- // on the current message
- Object clientIdProp = getMessageContext().get(OAuthConstants.CLIENT_ID);
- if (clientIdProp != null) {
- client = getClient(clientIdProp.toString());
- // TODO: consider matching client.getUserSubject().getLoginName()
- // against principal.getName() ?
+ // Most likely a container-level authentication, possibly 2-way TLS,
+ // Check if the mapping between Principal and Client Id has been done in a filter
+ String clientId = (String)getMessageContext().get(OAuthConstants.CLIENT_ID);
+ if (StringUtils.isEmpty(clientId) && clientIdProvider != null) {
+ // Check Custom ClientIdProvider
+ clientId = clientIdProvider.getClientId(getMessageContext());
}
+ if (!StringUtils.isEmpty(clientId)) {
+ client = getClient(clientId);
+ }
}
- } else {
- // the client id and secret are expected to be in the Basic scheme data
- String[] parts =
- AuthorizationUtils.getAuthorizationParts(getMessageContext());
- if (OAuthConstants.BASIC_SCHEME.equalsIgnoreCase(parts[0])) {
- String[] authInfo = AuthorizationUtils.getBasicAuthParts(parts[1]);
- client = getAndValidateClient(authInfo[0], authInfo[1]);
+ }
+
+ if (client == null) {
+ TLSSessionInfo tlsSessionInfo =
+ (TLSSessionInfo)getMessageContext().get(TLSSessionInfo.class.getName());
+ if (tlsSessionInfo != null) {
+ client = getClientFromTLSCertificates(sc, tlsSessionInfo);
+ } else {
+ // Basic Authentication is expected by default
+ client = getClientFromBasicAuthScheme();
}
}
@@ -89,20 +99,94 @@ public class AbstractTokenService extends AbstractOAuthService {
// Get the Client and check the id and secret
protected Client getAndValidateClient(String clientId, String clientSecret) {
Client client = getClient(clientId);
+ if (clientSecret != null
+ && (client.getClientCredentialType() == null
+ || !ClientCredentialType.PASSWORD.equals(client.getClientCredentialType()))) {
+ throw ExceptionUtils.toNotAuthorizedException(null, null);
+ }
if (canSupportPublicClients
&& !client.isConfidential()
- && client.getClientSecret() == null
+ && client.getClientCredential() == null
&& clientSecret == null) {
return client;
}
- if (clientSecret == null || client.getClientSecret() == null
+ if (clientSecret == null || client.getClientCredential() == null
|| !client.getClientId().equals(clientId)
- || !client.getClientSecret().equals(clientSecret)) {
+ || !client.getClientCredential().equals(clientSecret)) {
throw ExceptionUtils.toNotAuthorizedException(null, null);
}
return client;
}
+ protected Client getClientFromBasicAuthScheme() {
+ String[] parts = AuthorizationUtils.getAuthorizationParts(getMessageContext());
+ if (OAuthConstants.BASIC_SCHEME.equalsIgnoreCase(parts[0])) {
+ String[] authInfo = AuthorizationUtils.getBasicAuthParts(parts[1]);
+ return getAndValidateClient(authInfo[0], authInfo[1]);
+ } else {
+ return null;
+ }
+ }
+
+ 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();
+ }
+ }
+ return client;
+ }
+
+ protected String getClientIdFromTLSCertificates(SecurityContext sc, TLSSessionInfo tlsInfo) {
+ Certificate[] clientCerts = tlsInfo.getPeerCertificates();
+ if (clientCerts != null && clientCerts.length > 0) {
+ X500Principal x509Principal = ((X509Certificate)clientCerts[0]).getSubjectX500Principal();
+ return x509Principal.getName();
+ }
+ return null;
+ }
+
+ protected void validateTwoWayTlsClient(SecurityContext sc, TLSSessionInfo tlsSessionInfo, Client client) {
+ ClientCredentialType credType = client.getClientCredentialType();
+ if (credType != ClientCredentialType.X509CERTIFICATE && credType != ClientCredentialType.PUBLIC_KEY) {
+ reportInvalidClient();
+ } else if (client.getClientCredential() != null) {
+ // Client has a Base64 encoded representation of the certificate loaded
+ // so lets validate the TLS certificates
+ compareCertificates(tlsSessionInfo, client.getClientCredential(), credType);
+ }
+ }
+
+ protected void compareCertificates(TLSSessionInfo tlsInfo,
+ String base64EncodedCert,
+ ClientCredentialType type) {
+ Certificate[] clientCerts = tlsInfo.getPeerCertificates();
+ try {
+ X509Certificate cert = (X509Certificate)clientCerts[0];
+ byte[] encodedKey = type == ClientCredentialType.PUBLIC_KEY
+ ? cert.getPublicKey().getEncoded() : cert.getEncoded();
+ byte[] clientKey = Base64Utility.decode(base64EncodedCert);
+ if (Arrays.equals(encodedKey, clientKey)) {
+ return;
+ }
+ } catch (Exception ex) {
+ reportInvalidClient();
+ }
+ }
+
+
+
protected Response handleException(OAuthServiceException ex, String error) {
OAuthError customError = ex.getError();
if (writeCustomErrors && customError != null) {
@@ -168,4 +252,8 @@ public class AbstractTokenService extends AbstractOAuthService {
public void setWriteCustomErrors(boolean writeCustomErrors) {
this.writeCustomErrors = writeCustomErrors;
}
+
+ public void setClientIdProvider(ClientIdProvider clientIdProvider) {
+ this.clientIdProvider = clientIdProvider;
+ }
}
http://git-wip-us.apache.org/repos/asf/cxf/blob/5f1a556b/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 a4b48ce..a345204 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.getClientSecret() == null;
+ return canSupportPublicClients && !c.isConfidential() && c.getClientCredential() == null;
}
@Override
http://git-wip-us.apache.org/repos/asf/cxf/blob/5f1a556b/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 6f7872c..a6dd2bb 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
@@ -30,6 +30,7 @@ import java.util.Map;
import javax.crypto.SecretKey;
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.OAuthPermission;
import org.apache.cxf.rs.security.oauth2.common.ServerAccessToken;
import org.apache.cxf.rs.security.oauth2.common.UserSubject;
@@ -322,16 +323,17 @@ public final class ModelEncryptionSupport {
private static Client recreateClientInternal(String sequence) {
String[] parts = getParts(sequence);
- Client c = new Client(parts[0], 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]));
+ Client c = new Client(parts[0], parts[1], ClientCredentialType.valueOf(parts[2]),
+ 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]));
return c;
}
private static String tokenizeClient(Client client) {
@@ -340,7 +342,10 @@ public final class ModelEncryptionSupport {
state.append(tokenizeString(client.getClientId()));
state.append(SEP);
// 1: secret
- state.append(tokenizeString(client.getClientSecret()));
+ state.append(tokenizeString(client.getClientCredential()));
+ state.append(SEP);
+ // 1.1: secret type
+ state.append(tokenizeString(client.getClientCredentialType().toString()));
state.append(SEP);
// 2: confidentiality
state.append(client.isConfidential());
http://git-wip-us.apache.org/repos/asf/cxf/blob/5f1a556b/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 30d2d45..47a2f80 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
@@ -179,7 +179,7 @@ public class EncryptionUtilsTest extends Assert {
new ByteArrayInputStream(decrypted.getBytes()));
assertEquals(c.getClientId(), c2.getClientId());
- assertEquals(c.getClientSecret(), c2.getClientSecret());
+ assertEquals(c.getClientCredential(), c2.getClientCredential());
assertTrue(c2.isConfidential());
assertEquals("subject", c2.getSubject().getLogin());
assertEquals("id", c2.getSubject().getId());
http://git-wip-us.apache.org/repos/asf/cxf/blob/5f1a556b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/JAXRSOAuth2Test.java
----------------------------------------------------------------------
diff --git a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/JAXRSOAuth2Test.java b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/JAXRSOAuth2Test.java
index 10db4a9..500037e 100644
--- a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/JAXRSOAuth2Test.java
+++ b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/JAXRSOAuth2Test.java
@@ -101,6 +101,15 @@ public class JAXRSOAuth2Test extends AbstractBusClientServerTestBase {
}
@Test
+ public void testTwoWayTLSAuthentication() throws Exception {
+ String address = "https://localhost:" + PORT + "/oauth2/token";
+ WebClient wc = createWebClient(address);
+
+ ClientAccessToken at = OAuthClientUtils.getAccessToken(wc, new CustomGrant());
+ assertNotNull(at.getTokenKey());
+ }
+
+ @Test
public void testSAML2BearerAuthenticationInterceptor() throws Exception {
String address = "https://localhost:" + PORT + "/oauth2-auth/token";
WebClient wc = createWebClientWithProps(address);
http://git-wip-us.apache.org/repos/asf/cxf/blob/5f1a556b/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 d811e07..460129a 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
@@ -18,10 +18,13 @@
*/
package org.apache.cxf.systest.jaxrs.security.oauth2;
+import java.util.HashMap;
import java.util.List;
+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.OAuthPermission;
import org.apache.cxf.rs.security.oauth2.common.ServerAccessToken;
import org.apache.cxf.rs.security.oauth2.common.UserSubject;
@@ -33,12 +36,27 @@ import org.apache.cxf.rs.security.oauth2.tokens.bearer.BearerAccessToken;
public class OAuthDataProviderImpl implements OAuthDataProvider {
- @Override
- public Client getClient(String clientId) throws OAuthServiceException {
+ private Map<String, Client> clients = new HashMap<String, Client>();
+
+ public OAuthDataProviderImpl() {
Client client = new Client("alice", "alice", true);
client.getAllowedGrantTypes().add(Constants.SAML2_BEARER_GRANT);
client.getAllowedGrantTypes().add("custom_grant");
- return client;
+ clients.put(client.getClientId(), client);
+
+ Client client2 = new Client("CN=whateverhost.com,OU=Morpit,O=ApacheTest,L=Syracuse,C=US",
+ null,
+ ClientCredentialType.X509CERTIFICATE,
+ true,
+ null,
+ null);
+ client.getAllowedGrantTypes().add("custom_grant");
+ clients.put(client2.getClientId(), client2);
+ }
+
+ @Override
+ public Client getClient(String clientId) throws OAuthServiceException {
+ return clients.get(clientId);
}
@Override