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 2016/05/20 08:50:14 UTC
cxf git commit: [CXF-6909] Adding JCache OAuth2 providers,
patch from Luca Burgazzoli applied with thanks, This closes #137
Repository: cxf
Updated Branches:
refs/heads/master c681373b5 -> 2b1607831
[CXF-6909] Adding JCache OAuth2 providers, patch from Luca Burgazzoli applied with thanks, This closes #137
Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/2b160783
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/2b160783
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/2b160783
Branch: refs/heads/master
Commit: 2b1607831ccf97909122eae9247116d9a075c7cf
Parents: c681373
Author: Sergey Beryozkin <sb...@gmail.com>
Authored: Fri May 20 09:49:59 2016 +0100
Committer: Sergey Beryozkin <sb...@gmail.com>
Committed: Fri May 20 09:49:59 2016 +0100
----------------------------------------------------------------------
parent/pom.xml | 2 +
rt/rs/security/oauth-parent/oauth2/pom.xml | 29 ++-
.../grants/code/JCacheCodeDataProvider.java | 126 +++++++++++
.../provider/JCacheOAuthDataProvider.java | 215 ++++++++++++++++++
.../grants/code/JCacheCodeDataProviderTest.java | 105 +++++++++
.../provider/JCacheOAuthDataProviderTest.java | 217 +++++++++++++++++++
.../src/test/resources/cxf-oauth2-ehcache3.xml | 27 +++
7 files changed, 716 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cxf/blob/2b160783/parent/pom.xml
----------------------------------------------------------------------
diff --git a/parent/pom.xml b/parent/pom.xml
index ce1dc37..5f256d4 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -83,6 +83,7 @@
<cxf.derby.version>10.2.2.0</cxf.derby.version>
<cxf.dropwizard.version>3.1.2</cxf.dropwizard.version>
<cxf.ehcache.version>2.10.1</cxf.ehcache.version>
+ <cxf.ehcache3.version>3.0.1</cxf.ehcache3.version>
<cxf.fastinfoset.bundle.version>1.2.13_1</cxf.fastinfoset.bundle.version>
<cxf.guava.version>18.0</cxf.guava.version>
<cxf.hazelcast.version>1.9.4</cxf.hazelcast.version>
@@ -99,6 +100,7 @@
<cxf.mina.version>2.0.13</cxf.mina.version>
<cxf.rx.java.version>1.1.3</cxf.rx.java.version>
<cxf.javax.annotation-api.version>1.2</cxf.javax.annotation-api.version>
+ <cxf.jcache.version>1.0.0</cxf.jcache.version>
<cxf.geronimo.jms.version>1.1.1</cxf.geronimo.jms.version>
<cxf.geronimo.j2ee.management.version>1.0.1</cxf.geronimo.j2ee.management.version>
<cxf.geronimo.jpa.version>1.0</cxf.geronimo.jpa.version>
http://git-wip-us.apache.org/repos/asf/cxf/blob/2b160783/rt/rs/security/oauth-parent/oauth2/pom.xml
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2/pom.xml b/rt/rs/security/oauth-parent/oauth2/pom.xml
index bb8ee54..08f0a1e 100644
--- a/rt/rs/security/oauth-parent/oauth2/pom.xml
+++ b/rt/rs/security/oauth-parent/oauth2/pom.xml
@@ -62,11 +62,18 @@
<optional>true</optional>
</dependency>
<dependency>
- <groupId>net.sf.ehcache</groupId>
- <artifactId>ehcache</artifactId>
- <version>${cxf.ehcache.version}</version>
- <scope>provided</scope>
- <optional>true</optional>
+ <groupId>net.sf.ehcache</groupId>
+ <artifactId>ehcache</artifactId>
+ <version>${cxf.ehcache.version}</version>
+ <scope>provided</scope>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <groupId>javax.cache</groupId>
+ <artifactId>cache-api</artifactId>
+ <version>${cxf.jcache.version}</version>
+ <scope>provided</scope>
+ <optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
@@ -102,6 +109,12 @@
<version>${hsqldb.version}</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.ehcache</groupId>
+ <artifactId>ehcache</artifactId>
+ <version>${cxf.ehcache3.version}</version>
+ <scope>test</scope>
+ </dependency>
<!--
<dependency>
<groupId>org.apache.openjpa</groupId>
@@ -116,6 +129,12 @@
<version>${hibernate.em.version}</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-nop</artifactId>
+ <version>${cxf.slf4j.version}</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
http://git-wip-us.apache.org/repos/asf/cxf/blob/2b160783/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/code/JCacheCodeDataProvider.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/code/JCacheCodeDataProvider.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/code/JCacheCodeDataProvider.java
new file mode 100644
index 0000000..867e99f
--- /dev/null
+++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/code/JCacheCodeDataProvider.java
@@ -0,0 +1,126 @@
+/**
+ * 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.grants.code;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import javax.cache.Cache;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.BusFactory;
+import org.apache.cxf.rs.security.oauth2.common.Client;
+import org.apache.cxf.rs.security.oauth2.common.UserSubject;
+import org.apache.cxf.rs.security.oauth2.provider.JCacheOAuthDataProvider;
+import org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException;
+
+public class JCacheCodeDataProvider extends JCacheOAuthDataProvider
+ implements AuthorizationCodeDataProvider {
+ public static final String CODE_GRANT_CACHE_KEY = "cxf.oauth2.codegrant.cache";
+
+ private long codeLifetime = 10 * 60;
+ private Cache<String, ServerAuthorizationCodeGrant> grantCache;
+
+ protected JCacheCodeDataProvider() throws Exception {
+ this(DEFAULT_CONFIG_URL, BusFactory.getThreadDefaultBus(true));
+ }
+
+ protected JCacheCodeDataProvider(String configFileURL, Bus bus) throws Exception {
+ this(configFileURL, bus, CLIENT_CACHE_KEY, CODE_GRANT_CACHE_KEY,
+ ACCESS_TOKEN_CACHE_KEY, REFRESH_TOKEN_CACHE_KEY);
+ }
+
+ protected JCacheCodeDataProvider(String configFileURL,
+ Bus bus,
+ String clientCacheKey,
+ String codeCacheKey,
+ String accessTokenKey,
+ String refreshTokenKey) throws Exception {
+ super(configFileURL, bus, clientCacheKey, accessTokenKey, refreshTokenKey);
+ grantCache = createCache(cacheManager, codeCacheKey, String.class, ServerAuthorizationCodeGrant.class);
+ }
+
+ @Override
+ protected void doRemoveClient(Client c) {
+ for (ServerAuthorizationCodeGrant grant : getCodeGrants(c, null)) {
+ removeCodeGrant(grant.getCode());
+ }
+
+ super.doRemoveClient(c);
+ }
+
+ @Override
+ public ServerAuthorizationCodeGrant createCodeGrant(AuthorizationCodeRegistration reg)
+ throws OAuthServiceException {
+ ServerAuthorizationCodeGrant grant = AbstractCodeDataProvider.initCodeGrant(reg, codeLifetime);
+ grantCache.put(grant.getCode(), grant);
+
+ return grant;
+ }
+
+ @Override
+ public List<ServerAuthorizationCodeGrant> getCodeGrants(Client c, UserSubject sub) {
+ final Set<String> toRemove = new HashSet<>();
+ final List<ServerAuthorizationCodeGrant> grants = new ArrayList<>();
+
+ for (Iterator<Cache.Entry<String, ServerAuthorizationCodeGrant>> it = grantCache.iterator(); it.hasNext();) {
+ Cache.Entry<String, ServerAuthorizationCodeGrant> entry = it.next();
+ ServerAuthorizationCodeGrant grant = entry.getValue();
+
+ if (!isExpired(grant)) {
+ toRemove.add(entry.getKey());
+ } else if (AbstractCodeDataProvider.isCodeMatched(grant, c, sub)) {
+ grants.add(grant);
+ }
+ }
+
+ grantCache.removeAll(toRemove);
+
+ return grants;
+ }
+
+ @Override
+ public ServerAuthorizationCodeGrant removeCodeGrant(String code) throws OAuthServiceException {
+ ServerAuthorizationCodeGrant grant = getCodeGrant(code);
+ if (grant != null) {
+ grantCache.remove(code);
+ }
+ return grant;
+ }
+
+ public void setCodeLifetime(long codeLifetime) {
+ this.codeLifetime = codeLifetime;
+ }
+
+ protected ServerAuthorizationCodeGrant getCodeGrant(String code) throws OAuthServiceException {
+ ServerAuthorizationCodeGrant grant = grantCache.get(code);
+ if (grant != null && isExpired(grant)) {
+ grantCache.remove(code);
+ grant = null;
+ }
+
+ return grant;
+ }
+
+ protected static boolean isExpired(ServerAuthorizationCodeGrant grant) {
+ return System.currentTimeMillis() < (grant.getIssuedAt() + grant.getExpiresIn());
+ }
+}
http://git-wip-us.apache.org/repos/asf/cxf/blob/2b160783/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/JCacheOAuthDataProvider.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/JCacheOAuthDataProvider.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/JCacheOAuthDataProvider.java
new file mode 100644
index 0000000..3a2bbb8
--- /dev/null
+++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/JCacheOAuthDataProvider.java
@@ -0,0 +1,215 @@
+/**
+ * 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 java.net.URI;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import javax.cache.Cache;
+import javax.cache.CacheManager;
+import javax.cache.Caching;
+import javax.cache.configuration.MutableConfiguration;
+import javax.cache.spi.CachingProvider;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.BusFactory;
+import org.apache.cxf.rs.security.oauth2.common.Client;
+import org.apache.cxf.rs.security.oauth2.common.ServerAccessToken;
+import org.apache.cxf.rs.security.oauth2.common.UserSubject;
+import org.apache.cxf.rs.security.oauth2.tokens.refresh.RefreshToken;
+
+import static org.apache.cxf.jaxrs.utils.ResourceUtils.getClasspathResourceURL;
+
+public class JCacheOAuthDataProvider extends AbstractOAuthDataProvider {
+ public static final String CLIENT_CACHE_KEY = "cxf.oauth2.client.cache";
+ public static final String ACCESS_TOKEN_CACHE_KEY = "cxf.oauth2.accesstoken.cache";
+ public static final String REFRESH_TOKEN_CACHE_KEY = "cxf.oauth2.refreshtoken.cache";
+ public static final String DEFAULT_CONFIG_URL = "cxf-oauth2-ehcache3.xml";
+
+ protected final CacheManager cacheManager;
+ private final Cache<String, Client> clientCache;
+ private final Cache<String, ServerAccessToken> accessTokenCache;
+ private final Cache<String, RefreshToken> refreshTokenCache;
+
+ public JCacheOAuthDataProvider() throws Exception {
+ this(DEFAULT_CONFIG_URL, BusFactory.getThreadDefaultBus(true));
+ }
+
+ public JCacheOAuthDataProvider(String configFileURL, Bus bus) throws Exception {
+ this(configFileURL, bus, CLIENT_CACHE_KEY, ACCESS_TOKEN_CACHE_KEY, REFRESH_TOKEN_CACHE_KEY);
+ }
+
+ public JCacheOAuthDataProvider(String configFileURL,
+ Bus bus,
+ String clientCacheKey,
+ String accessTokenKey,
+ String refreshTokenKey) throws Exception {
+
+ cacheManager = createCacheManager(configFileURL, bus);
+ clientCache = createCache(cacheManager, clientCacheKey, String.class, Client.class);
+ accessTokenCache = createCache(cacheManager, accessTokenKey, String.class, ServerAccessToken.class);
+ refreshTokenCache = createCache(cacheManager, refreshTokenKey, String.class, RefreshToken.class);
+ }
+
+ @Override
+ public Client getClient(String clientId) throws OAuthServiceException {
+ return clientCache.get(clientId);
+ }
+
+ public void setClient(Client client) {
+ clientCache.put(client.getClientId(), client);
+ }
+
+ @Override
+ protected void doRemoveClient(Client c) {
+ clientCache.remove(c.getClientId());
+ }
+
+ @Override
+ public List<Client> getClients(UserSubject resourceOwner) {
+ List<Client> clients = new ArrayList<>();
+ for (Iterator<Cache.Entry<String, Client>> it = clientCache.iterator(); it.hasNext();) {
+ Cache.Entry<String, Client> entry = it.next();
+ Client client = entry.getValue();
+
+ if (isClientMatched(client, resourceOwner)) {
+ clients.add(client);
+ }
+ }
+
+ return clients;
+ }
+
+ @Override
+ public List<ServerAccessToken> getAccessTokens(Client c, UserSubject sub) {
+ return getTokens(accessTokenCache, c, sub);
+ }
+
+ @Override
+ public List<RefreshToken> getRefreshTokens(Client c, UserSubject sub) {
+ return getTokens(refreshTokenCache, c, sub);
+ }
+
+ @Override
+ public ServerAccessToken getAccessToken(String accessTokenKey) throws OAuthServiceException {
+ return getToken(accessTokenCache, accessTokenKey);
+ }
+
+ @Override
+ protected void doRevokeAccessToken(ServerAccessToken at) {
+ accessTokenCache.remove(at.getTokenKey());
+ }
+
+ @Override
+ protected RefreshToken getRefreshToken(String refreshTokenKey) {
+ return getToken(refreshTokenCache, refreshTokenKey);
+ }
+
+ @Override
+ protected void doRevokeRefreshToken(RefreshToken rt) {
+ refreshTokenCache.remove(rt.getTokenKey());
+ }
+
+ @Override
+ protected void saveAccessToken(ServerAccessToken serverToken) {
+ accessTokenCache.put(serverToken.getTokenKey(), serverToken);
+ }
+
+ @Override
+ protected void saveRefreshToken(RefreshToken refreshToken) {
+ refreshTokenCache.put(refreshToken.getTokenKey(), refreshToken);
+ }
+
+ @Override
+ public void close() {
+ cacheManager.close();
+ }
+
+ protected static <K, V extends ServerAccessToken> V getToken(Cache<K, V> cache, K key) {
+ V token = cache.get(key);
+ if (token != null && isExpired(token)) {
+ cache.remove(key);
+ token = null;
+ }
+
+ return token;
+ }
+
+ protected static <K, V extends ServerAccessToken> List<V> getTokens(Cache<K, V> cache,
+ Client client, UserSubject sub) {
+ final Set<K> toRemove = new HashSet<>();
+ final List<V> tokens = new ArrayList<>();
+
+ for (Iterator<Cache.Entry<K, V>> it = cache.iterator(); it.hasNext();) {
+ Cache.Entry<K, V> entry = it.next();
+ V token = entry.getValue();
+
+ if (!isExpired(token)) {
+ toRemove.add(entry.getKey());
+ } else if (isTokenMatched(token, client, sub)) {
+ tokens.add(token);
+ }
+ }
+
+ cache.removeAll(toRemove);
+
+ return tokens;
+ }
+
+ protected static boolean isExpired(ServerAccessToken token) {
+ return System.currentTimeMillis() < (token.getIssuedAt() + token.getExpiresIn());
+ }
+
+ protected static CacheManager createCacheManager(String configFile, Bus bus) throws Exception {
+ if (bus == null) {
+ bus = BusFactory.getThreadDefaultBus(true);
+ }
+
+ CachingProvider provider = Caching.getCachingProvider();
+
+ URI configFileURI;
+ try {
+ configFileURI = getClasspathResourceURL(configFile, JCacheOAuthDataProvider.class, bus).toURI();
+ } catch (Exception ex) {
+ configFileURI = provider.getDefaultURI();
+ }
+
+ return provider.getCacheManager(configFileURI, Thread.currentThread().getContextClassLoader());
+ }
+
+ protected static <K, V> Cache<K, V> createCache(CacheManager cacheManager,
+ String cacheKey, Class<K> keyType, Class<V> valueType) {
+
+ Cache<K, V> cache = cacheManager.getCache(cacheKey, keyType, valueType);
+ if (cache == null) {
+ cache = cacheManager.createCache(
+ cacheKey,
+ new MutableConfiguration<K, V>()
+ .setTypes(keyType, valueType)
+ .setStoreByValue(true)
+ .setStatisticsEnabled(false)
+ );
+ }
+
+ return cache;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cxf/blob/2b160783/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/grants/code/JCacheCodeDataProviderTest.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/grants/code/JCacheCodeDataProviderTest.java b/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/grants/code/JCacheCodeDataProviderTest.java
new file mode 100644
index 0000000..eb698b7
--- /dev/null
+++ b/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/grants/code/JCacheCodeDataProviderTest.java
@@ -0,0 +1,105 @@
+/**
+ * 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.grants.code;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.cxf.rs.security.oauth2.common.Client;
+import org.apache.cxf.rs.security.oauth2.common.UserSubject;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class JCacheCodeDataProviderTest extends Assert {
+ private JCacheCodeDataProvider provider;
+
+ @Before
+ public void setUp() throws Exception {
+ provider = new JCacheCodeDataProvider();
+ }
+
+ @Ignore
+ @Test
+ public void testAddGetDeleteCodeGrants() {
+ Client c = addClient("111", "bob");
+
+ AuthorizationCodeRegistration atr = new AuthorizationCodeRegistration();
+ atr.setClient(c);
+ atr.setApprovedScope(Collections.singletonList("a"));
+ atr.setSubject(c.getResourceOwnerSubject());
+
+ ServerAuthorizationCodeGrant grant = provider.createCodeGrant(atr);
+
+ List<ServerAuthorizationCodeGrant> grants = provider.getCodeGrants(c, c.getResourceOwnerSubject());
+ assertNotNull(grants);
+ assertEquals(1, grants.size());
+ assertEquals(grant.getCode(), grants.get(0).getCode());
+
+ grants = provider.getCodeGrants(c, null);
+ assertNotNull(grants);
+ assertEquals(1, grants.size());
+ assertEquals(grant.getCode(), grants.get(0).getCode());
+
+ ServerAuthorizationCodeGrant grant2 = provider.removeCodeGrant(grant.getCode());
+ assertEquals(grant.getCode(), grant2.getCode());
+
+ grants = provider.getCodeGrants(c, null);
+ assertNotNull(grants);
+ assertEquals(0, grants.size());
+ }
+
+ @Ignore
+ @Test
+ public void testAddGetDeleteCodeGrants2() {
+ Client c = addClient("111", "bob");
+
+ AuthorizationCodeRegistration atr = new AuthorizationCodeRegistration();
+ atr.setClient(c);
+ atr.setApprovedScope(Collections.singletonList("a"));
+ atr.setSubject(c.getResourceOwnerSubject());
+
+ provider.createCodeGrant(atr);
+
+ List<ServerAuthorizationCodeGrant> grants = provider.getCodeGrants(c, c.getResourceOwnerSubject());
+ assertNotNull(grants);
+ assertEquals(1, grants.size());
+ provider.removeClient(c.getClientId());
+ grants = provider.getCodeGrants(c, c.getResourceOwnerSubject());
+ assertNotNull(grants);
+ assertEquals(0, grants.size());
+ }
+
+ private Client addClient(String clientId, String userLogin) {
+ Client c = new Client();
+ c.setRedirectUris(Collections.singletonList("http://client/redirect"));
+ c.setClientId(clientId);
+ c.setResourceOwnerSubject(new UserSubject(userLogin));
+ provider.setClient(c);
+ return c;
+ }
+ @After
+ public void tearDown() throws Exception {
+ if (provider != null) {
+ provider.close();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/cxf/blob/2b160783/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/provider/JCacheOAuthDataProviderTest.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/provider/JCacheOAuthDataProviderTest.java b/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/provider/JCacheOAuthDataProviderTest.java
new file mode 100644
index 0000000..2ed60ad
--- /dev/null
+++ b/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/provider/JCacheOAuthDataProviderTest.java
@@ -0,0 +1,217 @@
+/**
+ * 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 java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+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.OAuthPermission;
+import org.apache.cxf.rs.security.oauth2.common.ServerAccessToken;
+import org.apache.cxf.rs.security.oauth2.common.UserSubject;
+import org.apache.cxf.rs.security.oauth2.tokens.refresh.RefreshToken;
+import org.apache.cxf.rs.security.oauth2.utils.OAuthConstants;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class JCacheOAuthDataProviderTest extends Assert {
+ private JCacheOAuthDataProvider provider;
+
+ @Before
+ public void setUp() throws Exception {
+ provider = new JCacheOAuthDataProvider();
+ }
+
+ @Test
+ public void testAddGetDeleteClient() {
+ Client c = addClient("12345", "alice");
+ Client c2 = provider.getClient(c.getClientId());
+ compareClients(c, c2);
+
+ c2.setClientSecret("567");
+ provider.setClient(c2);
+ Client c22 = provider.getClient(c.getClientId());
+ compareClients(c2, c22);
+
+ provider.removeClient(c.getClientId());
+ Client c3 = provider.getClient(c.getClientId());
+ assertNull(c3);
+ }
+
+ @Test
+ public void testAddGetDeleteClients() {
+ Client c = addClient("12345", "alice");
+ Client c2 = addClient("56789", "alice");
+ Client c3 = addClient("09876", "bob");
+
+ List<Client> aliceClients = provider.getClients(new UserSubject("alice"));
+ assertNotNull(aliceClients);
+ assertEquals(2, aliceClients.size());
+ compareClients(c, aliceClients.get(0).getClientId().equals("12345")
+ ? aliceClients.get(0) : aliceClients.get(1));
+ compareClients(c2, aliceClients.get(0).getClientId().equals("56789")
+ ? aliceClients.get(0) : aliceClients.get(1));
+
+ List<Client> bobClients = provider.getClients(new UserSubject("bob"));
+ assertNotNull(bobClients);
+ assertEquals(1, bobClients.size());
+ Client bobClient = bobClients.get(0);
+ compareClients(c3, bobClient);
+
+ List<Client> allClients = provider.getClients(null);
+ assertNotNull(allClients);
+ assertEquals(3, allClients.size());
+ provider.removeClient(c.getClientId());
+ provider.removeClient(c2.getClientId());
+ provider.removeClient(c3.getClientId());
+ allClients = provider.getClients(null);
+ assertNotNull(allClients);
+ assertEquals(0, allClients.size());
+ }
+
+ @Ignore
+ @Test
+ public void testAddGetDeleteAccessToken() {
+ Client c = addClient("101", "bob");
+
+ AccessTokenRegistration atr = new AccessTokenRegistration();
+ atr.setClient(c);
+ atr.setApprovedScope(Collections.singletonList("a"));
+ atr.setSubject(c.getResourceOwnerSubject());
+
+ ServerAccessToken at = provider.createAccessToken(atr);
+ ServerAccessToken at2 = provider.getAccessToken(at.getTokenKey());
+ assertEquals(at.getTokenKey(), at2.getTokenKey());
+ List<OAuthPermission> scopes = at2.getScopes();
+ assertNotNull(scopes);
+ assertEquals(1, scopes.size());
+ OAuthPermission perm = scopes.get(0);
+ assertEquals("a", perm.getPermission());
+
+ List<ServerAccessToken> tokens = provider.getAccessTokens(c, c.getResourceOwnerSubject());
+ assertNotNull(tokens);
+ assertEquals(1, tokens.size());
+ assertEquals(at.getTokenKey(), tokens.get(0).getTokenKey());
+
+ tokens = provider.getAccessTokens(c, null);
+ assertNotNull(tokens);
+ assertEquals(1, tokens.size());
+ assertEquals(at.getTokenKey(), tokens.get(0).getTokenKey());
+
+ tokens = provider.getAccessTokens(null, c.getResourceOwnerSubject());
+ assertNotNull(tokens);
+ assertEquals(1, tokens.size());
+ assertEquals(at.getTokenKey(), tokens.get(0).getTokenKey());
+
+ tokens = provider.getAccessTokens(null, null);
+ assertNotNull(tokens);
+ assertEquals(1, tokens.size());
+ assertEquals(at.getTokenKey(), tokens.get(0).getTokenKey());
+
+ provider.revokeToken(c, at.getTokenKey(), OAuthConstants.ACCESS_TOKEN);
+ assertNull(provider.getAccessToken(at.getTokenKey()));
+ }
+
+ @Ignore
+ @Test
+ public void testAddGetDeleteAccessToken2() {
+ Client c = addClient("102", "bob");
+
+ AccessTokenRegistration atr = new AccessTokenRegistration();
+ atr.setClient(c);
+ atr.setApprovedScope(Collections.singletonList("a"));
+ atr.setSubject(c.getResourceOwnerSubject());
+
+ provider.createAccessToken(atr);
+ List<ServerAccessToken> tokens = provider.getAccessTokens(c, null);
+ assertNotNull(tokens);
+ assertEquals(1, tokens.size());
+
+ provider.removeClient(c.getClientId());
+
+ tokens = provider.getAccessTokens(c, null);
+ assertNotNull(tokens);
+ assertEquals(0, tokens.size());
+ }
+
+ @Ignore
+ @Test
+ public void testAddGetDeleteRefreshToken() {
+ Client c = addClient("101", "bob");
+
+ AccessTokenRegistration atr = new AccessTokenRegistration();
+ atr.setClient(c);
+ atr.setApprovedScope(Arrays.asList("a", "refreshToken"));
+ atr.setSubject(c.getResourceOwnerSubject());
+
+ ServerAccessToken at = provider.createAccessToken(atr);
+ ServerAccessToken at2 = provider.getAccessToken(at.getTokenKey());
+ assertEquals(at.getTokenKey(), at2.getTokenKey());
+ List<OAuthPermission> scopes = at2.getScopes();
+ assertNotNull(scopes);
+ assertEquals(2, scopes.size());
+ OAuthPermission perm = scopes.get(0);
+ assertEquals("a", perm.getPermission());
+ OAuthPermission perm2 = scopes.get(1);
+ assertEquals("refreshToken", perm2.getPermission());
+
+ RefreshToken rt = provider.getRefreshToken(at2.getRefreshToken());
+ assertNotNull(rt);
+ assertEquals(at2.getTokenKey(), rt.getAccessTokens().get(0));
+
+ List<RefreshToken> tokens = provider.getRefreshTokens(c, c.getResourceOwnerSubject());
+ assertNotNull(tokens);
+ assertEquals(1, tokens.size());
+ assertEquals(rt.getTokenKey(), tokens.get(0).getTokenKey());
+
+ provider.revokeToken(c, rt.getTokenKey(), OAuthConstants.REFRESH_TOKEN);
+
+ assertNull(provider.getRefreshToken(rt.getTokenKey()));
+ }
+
+ private Client addClient(String clientId, String userLogin) {
+ Client c = new Client();
+ c.setRedirectUris(Collections.singletonList("http://client/redirect"));
+ c.setClientId(clientId);
+ c.setClientSecret("123");
+ c.setResourceOwnerSubject(new UserSubject(userLogin));
+ provider.setClient(c);
+ return c;
+ }
+ private void compareClients(Client c, Client c2) {
+ assertNotNull(c2);
+ assertEquals(c.getClientId(), c2.getClientId());
+ assertEquals(1, c.getRedirectUris().size());
+ assertEquals(1, c2.getRedirectUris().size());
+ assertEquals("http://client/redirect", c.getRedirectUris().get(0));
+ assertEquals(c.getResourceOwnerSubject().getLogin(), c2.getResourceOwnerSubject().getLogin());
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ if (provider != null) {
+ provider.close();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/cxf/blob/2b160783/rt/rs/security/oauth-parent/oauth2/src/test/resources/cxf-oauth2-ehcache3.xml
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2/src/test/resources/cxf-oauth2-ehcache3.xml b/rt/rs/security/oauth-parent/oauth2/src/test/resources/cxf-oauth2-ehcache3.xml
new file mode 100644
index 0000000..50ebfae
--- /dev/null
+++ b/rt/rs/security/oauth-parent/oauth2/src/test/resources/cxf-oauth2-ehcache3.xml
@@ -0,0 +1,27 @@
+<config
+ xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
+ xmlns='http://www.ehcache.org/v3'
+ xmlns:jsr107='http://www.ehcache.org/v3/jsr107'
+ xsi:schemaLocation="
+ http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core-3.0.xsd">
+
+ <cache alias="cxf.oauth2.client.cache">
+ <key-type>java.lang.String</key-type>
+ <value-type>org.apache.cxf.rs.security.oauth2.common.Client</value-type>
+ <heap unit="entries">100</heap>
+ <jsr107:mbeans enable-management="false" enable-statistics="false"/>
+ </cache>
+ <cache alias="cxf.oauth2.accesstoken.cache">
+ <key-type>java.lang.String</key-type>
+ <value-type>org.apache.cxf.rs.security.oauth2.common.ServerAccessToken</value-type>
+ <heap unit="entries">100</heap>
+ <jsr107:mbeans enable-management="false" enable-statistics="false"/>
+ </cache>
+ <cache alias="cxf.oauth2.refreshtoken.cache">
+ <key-type>java.lang.String</key-type>
+ <value-type>org.apache.cxf.rs.security.oauth2.tokens.refresh.RefreshToken</value-type>
+ <heap unit="entries">100</heap>
+ <jsr107:mbeans enable-management="false" enable-statistics="false"/>
+ </cache>
+
+</config>
\ No newline at end of file