From cbb51b050672671ec4870dac3b6b1faab129b2d6 Mon Sep 17 00:00:00 2001 From: Scott Battaglia Date: Sat, 27 Nov 2010 23:23:24 +0000 Subject: [PATCH] CASC-135 added encryption mechanism to distributed proxy granting ticket storage mechanisms --- ...cryptedProxyGrantingTicketStorageImpl.java | 92 +++++++++++++++++++ ...0ProxyReceivingTicketValidationFilter.java | 16 ++++ .../cas/client/PublicTestHttpServer.java | 17 ++-- .../cas/client/jaas/CasLoginModuleTests.java | 37 +++++--- .../AbstractTicketValidatorTests.java | 2 +- .../validation/Cas10TicketValidatorTests.java | 16 ++-- .../Cas20ProxyTicketValidatorTests.java | 24 ++--- .../Cas20ServiceTicketValidatorTests.java | 23 ++--- .../Saml11TicketValidatorTests.java | 13 ++- .../resources/cas20ProxyTicketValidator.xml | 4 +- .../pom.xml | 7 ++ ...eBackedProxyGrantingTicketStorageImpl.java | 16 +++- ...edProxyGrantingTicketStorageImplTests.java | 27 ++++++ ...dBackedProxyGrantingTicketStorageImpl.java | 6 +- 14 files changed, 227 insertions(+), 73 deletions(-) create mode 100644 cas-client-core/src/main/java/org/jasig/cas/client/proxy/AbstractEncryptedProxyGrantingTicketStorageImpl.java create mode 100644 cas-client-support-distributed-ehcache/src/test/java/EhCacheBackedProxyGrantingTicketStorageImplTests.java diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/proxy/AbstractEncryptedProxyGrantingTicketStorageImpl.java b/cas-client-core/src/main/java/org/jasig/cas/client/proxy/AbstractEncryptedProxyGrantingTicketStorageImpl.java new file mode 100644 index 0000000..b9c3e4d --- /dev/null +++ b/cas-client-core/src/main/java/org/jasig/cas/client/proxy/AbstractEncryptedProxyGrantingTicketStorageImpl.java @@ -0,0 +1,92 @@ +package org.jasig.cas.client.proxy; + +import javax.crypto.Cipher; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.DESKeySpec; +import javax.crypto.spec.DESedeKeySpec; +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.NoSuchAlgorithmException; +import java.security.spec.InvalidKeySpecException; + +/** + * Provides encryption capabilities. Not entirely safe to configure since we have no way of controlling the + * key and cipher being set. + * + * @author Scott Battaglia + * @version $Revision$ $Date$ + * @since 3.2.0 + */ +public abstract class AbstractEncryptedProxyGrantingTicketStorageImpl implements ProxyGrantingTicketStorage { + + public static final String DEFAULT_ENCRYPTION_ALGORITHM = "DESede"; + + private Key key; + + private String cipherAlgorithm = DEFAULT_ENCRYPTION_ALGORITHM; + + public final void setSecretKey(final String key) throws NoSuchAlgorithmException, InvalidKeyException, InvalidKeySpecException { + this.key = SecretKeyFactory.getInstance(this.cipherAlgorithm).generateSecret(new DESedeKeySpec(key.getBytes())); + } + + public final void setSecretKey(final Key key) { + this.key = key; + } + + /** + * Note: you MUST call this method before calling setSecretKey if you're not using the default algorithm. You've been warned. + * + * @param cipherAlgorithm the cipher algorithm. + */ + public final void setCipherAlgorithm(final String cipherAlgorithm) { + this.cipherAlgorithm = cipherAlgorithm; + } + + public final void save(final String proxyGrantingTicketIou, final String proxyGrantingTicket) { + saveInternal(proxyGrantingTicketIou, encrypt(proxyGrantingTicket)); + } + + public final String retrieve(final String proxyGrantingTicketIou) { + return decrypt(retrieveInternal(proxyGrantingTicketIou)); + } + + protected abstract void saveInternal(String proxyGrantingTicketIou, String proxyGrantingTicket); + + protected abstract String retrieveInternal(String proxyGrantingTicketIou); + + private String encrypt(final String value) { + if (this.key == null) { + return value; + } + + if (value == null) { + return null; + } + + try { + final Cipher cipher = Cipher.getInstance(this.cipherAlgorithm); + cipher.init(Cipher.ENCRYPT_MODE, this.key); + return new String(cipher.doFinal(value.getBytes())); + } catch (final Exception e) { + throw new RuntimeException(e); + } + } + + private String decrypt(final String value) { + if (this.key == null) { + return value; + } + + if (value == null) { + return null; + } + + try { + final Cipher cipher = Cipher.getInstance(this.cipherAlgorithm); + cipher.init(Cipher.DECRYPT_MODE, this.key); + return new String(cipher.doFinal(value.getBytes())); + } catch (final Exception e) { + throw new RuntimeException(e); + } + } +} diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/validation/Cas20ProxyReceivingTicketValidationFilter.java b/cas-client-core/src/main/java/org/jasig/cas/client/validation/Cas20ProxyReceivingTicketValidationFilter.java index 6ec28da..efe067a 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/validation/Cas20ProxyReceivingTicketValidationFilter.java +++ b/cas-client-core/src/main/java/org/jasig/cas/client/validation/Cas20ProxyReceivingTicketValidationFilter.java @@ -76,6 +76,22 @@ public class Cas20ProxyReceivingTicketValidationFilter extends AbstractTicketVal if (proxyGrantingTicketStorageClass != null) { this.proxyGrantingTicketStorage = ReflectUtils.newInstance(proxyGrantingTicketStorageClass); + + if (this.proxyGrantingTicketStorage instanceof AbstractEncryptedProxyGrantingTicketStorageImpl) { + final AbstractEncryptedProxyGrantingTicketStorageImpl p = (AbstractEncryptedProxyGrantingTicketStorageImpl) this.proxyGrantingTicketStorage; + final String cipherAlgorithm = getPropertyFromInitParams(filterConfig, "cipherAlgorithm", AbstractEncryptedProxyGrantingTicketStorageImpl.DEFAULT_ENCRYPTION_ALGORITHM); + final String secretKey = getPropertyFromInitParams(filterConfig, "secretKey", null); + + p.setCipherAlgorithm(cipherAlgorithm); + + try { + if (secretKey != null) { + p.setSecretKey(secretKey); + } + } catch (final Exception e) { + throw new RuntimeException(e); + } + } } log.trace("Setting proxyReceptorUrl parameter: " + this.proxyReceptorUrl); diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/PublicTestHttpServer.java b/cas-client-core/src/test/java/org/jasig/cas/client/PublicTestHttpServer.java index 0cee4ad..e6ae620 100644 --- a/cas-client-core/src/test/java/org/jasig/cas/client/PublicTestHttpServer.java +++ b/cas-client-core/src/test/java/org/jasig/cas/client/PublicTestHttpServer.java @@ -54,18 +54,15 @@ public final class PublicTestHttpServer extends Thread { this.header = header.getBytes("ASCII"); } - public static synchronized PublicTestHttpServer instance() { - if (httpServer == null) { - try { - httpServer = new PublicTestHttpServer("test", "ASCII", "text/plain", 8085); - } catch (Exception e) { - throw new RuntimeException(e); - } - httpServer.start(); + public static synchronized PublicTestHttpServer instance(final int port) { + try { + final PublicTestHttpServer server = new PublicTestHttpServer("test", "ASCII", "text/plain", port); + server.start(); Thread.yield(); + return server; + } catch (Exception e) { + throw new RuntimeException(e); } - - return httpServer; } public void shutdown() { diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/jaas/CasLoginModuleTests.java b/cas-client-core/src/test/java/org/jasig/cas/client/jaas/CasLoginModuleTests.java index e122ddf..decb5a0 100644 --- a/cas-client-core/src/test/java/org/jasig/cas/client/jaas/CasLoginModuleTests.java +++ b/cas-client-core/src/test/java/org/jasig/cas/client/jaas/CasLoginModuleTests.java @@ -28,9 +28,12 @@ import java.util.Set; import javax.security.auth.Subject; import javax.security.auth.login.LoginException; -import junit.framework.TestCase; +import static org.junit.Assert.*; import org.jasig.cas.client.PublicTestHttpServer; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.Test; /** * Unit test for {@link CasLoginModule} class. @@ -39,8 +42,11 @@ import org.jasig.cas.client.PublicTestHttpServer; * @version $Revision$ * */ -public class CasLoginModuleTests extends TestCase { - private static final String CONST_CAS_SERVER_URL = "http://localhost:8085/"; +public class CasLoginModuleTests { + + private static final PublicTestHttpServer server = PublicTestHttpServer.instance(8091); + + private static final String CONST_CAS_SERVER_URL = "http://localhost:8091/"; private CasLoginModule module; @@ -48,10 +54,13 @@ public class CasLoginModuleTests extends TestCase { private Map options; - /** {@inheritDoc} */ - protected void setUp() throws Exception { - super.setUp(); - + @AfterClass + public static void classCleanUp() { + server.shutdown(); + } + + @Before + public void setUp() throws Exception { module = new CasLoginModule(); subject = new Subject(); options = new HashMap(); @@ -69,6 +78,7 @@ public class CasLoginModuleTests extends TestCase { * Test JAAS login success. * @throws Exception On errors. */ + @Test public void testLoginSuccess() throws Exception { final String USERNAME = "username"; final String SERVICE = "https://example.com/service"; @@ -77,7 +87,7 @@ public class CasLoginModuleTests extends TestCase { + "" + USERNAME + ""; - PublicTestHttpServer.instance().content = RESPONSE.getBytes(PublicTestHttpServer.instance().encoding); + server.content = RESPONSE.getBytes(server.encoding); module.initialize( subject, @@ -97,11 +107,12 @@ public class CasLoginModuleTests extends TestCase { * Test JAAS login failure. * @throws Exception On errors. */ + @Test public void testLoginFailure() throws Exception { final String SERVICE = "https://example.com/service"; final String TICKET = "ST-200000-aA5Yuvrxzpv8Tau1cYQ7-srv1"; final String RESPONSE = "Ticket ST-200000-aA5Yuvrxzpv8Tau1cYQ7-srv1 not recognized"; - PublicTestHttpServer.instance().content = RESPONSE.getBytes(PublicTestHttpServer.instance().encoding); + server.content = RESPONSE.getBytes(server.encoding); module.initialize( subject, new ServiceAndTicketCallbackHandler(SERVICE, TICKET), @@ -122,6 +133,7 @@ public class CasLoginModuleTests extends TestCase { * Test JAAS logout after successful login to ensure subject cleanup. * @throws Exception On errors. */ + @Test public void testLogout() throws Exception { testLoginSuccess(); module.logout(); @@ -132,7 +144,8 @@ public class CasLoginModuleTests extends TestCase { /** * Test assertion cache allows successive logins with same ticket to succeed. * @throws Exception On errors. - */ + */ + @Test public void testAssertionCaching() throws Exception { final String USERNAME = "username"; final String SERVICE = "https://example.com/service"; @@ -142,7 +155,7 @@ public class CasLoginModuleTests extends TestCase { + USERNAME + ""; final String RESPONSE2 = "Ticket ST-300000-aA5Yuvrxzpv8Tau1cYQ7-srv1 not recognized"; - PublicTestHttpServer.instance().content = RESPONSE1.getBytes(PublicTestHttpServer.instance().encoding); + server.content = RESPONSE1.getBytes(server.encoding); options.put("cacheAssertions", "true"); options.put("cacheTimeout", "1"); @@ -160,7 +173,7 @@ public class CasLoginModuleTests extends TestCase { module.logout(); assertEquals(0, subject.getPrincipals().size()); assertEquals(0, subject.getPrivateCredentials().size()); - PublicTestHttpServer.instance().content = RESPONSE2.getBytes(PublicTestHttpServer.instance().encoding); + server.content = RESPONSE2.getBytes(server.encoding); module.initialize( subject, new ServiceAndTicketCallbackHandler(SERVICE, TICKET), diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/validation/AbstractTicketValidatorTests.java b/cas-client-core/src/test/java/org/jasig/cas/client/validation/AbstractTicketValidatorTests.java index 6c07d21..fa6036f 100644 --- a/cas-client-core/src/test/java/org/jasig/cas/client/validation/AbstractTicketValidatorTests.java +++ b/cas-client-core/src/test/java/org/jasig/cas/client/validation/AbstractTicketValidatorTests.java @@ -28,7 +28,7 @@ package org.jasig.cas.client.validation; */ public abstract class AbstractTicketValidatorTests { - protected static final String CONST_CAS_SERVER_URL = "http://localhost:8085/"; + protected static final String CONST_CAS_SERVER_URL_PREFIX = "http://localhost:"; protected static final String CONST_USERNAME = "username"; } diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/validation/Cas10TicketValidatorTests.java b/cas-client-core/src/test/java/org/jasig/cas/client/validation/Cas10TicketValidatorTests.java index 80b76b9..2c3a2df 100644 --- a/cas-client-core/src/test/java/org/jasig/cas/client/validation/Cas10TicketValidatorTests.java +++ b/cas-client-core/src/test/java/org/jasig/cas/client/validation/Cas10TicketValidatorTests.java @@ -38,6 +38,8 @@ import static org.junit.Assert.*; */ public final class Cas10TicketValidatorTests extends AbstractTicketValidatorTests { + private static final PublicTestHttpServer server = PublicTestHttpServer.instance(8090); + private Cas10TicketValidator ticketValidator; public Cas10TicketValidatorTests() { @@ -46,18 +48,17 @@ public final class Cas10TicketValidatorTests extends AbstractTicketValidatorTest @AfterClass public static void classCleanUp() { - PublicTestHttpServer.instance().shutdown(); + server.shutdown(); } @Before public void setUp() throws Exception { - this.ticketValidator = new Cas10TicketValidator(CONST_CAS_SERVER_URL); + this.ticketValidator = new Cas10TicketValidator(CONST_CAS_SERVER_URL_PREFIX + "8090"); } @Test public void testNoResponse() throws Exception { - PublicTestHttpServer.instance().content = "no\n\n" - .getBytes(PublicTestHttpServer.instance().encoding); + server.content = "no\n\n".getBytes(server.encoding); try { this.ticketValidator.validate("testTicket", "myService"); @@ -70,8 +71,7 @@ public final class Cas10TicketValidatorTests extends AbstractTicketValidatorTest @Test public void testYesResponse() throws TicketValidationException, UnsupportedEncodingException { - PublicTestHttpServer.instance().content = "yes\nusername\n\n" - .getBytes(PublicTestHttpServer.instance().encoding); + server.content = "yes\nusername\n\n".getBytes(server.encoding); final Assertion assertion = this.ticketValidator.validate("testTicket", "myService"); assertEquals(CONST_USERNAME, assertion.getPrincipal().getName()); @@ -79,8 +79,8 @@ public final class Cas10TicketValidatorTests extends AbstractTicketValidatorTest @Test public void testBadResponse() throws UnsupportedEncodingException { - PublicTestHttpServer.instance().content = "falalala\n\n" - .getBytes(PublicTestHttpServer.instance().encoding); + server.content = "falalala\n\n" + .getBytes(server.encoding); try { this.ticketValidator.validate("testTicket", "myService"); diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/validation/Cas20ProxyTicketValidatorTests.java b/cas-client-core/src/test/java/org/jasig/cas/client/validation/Cas20ProxyTicketValidatorTests.java index 772060b..54f0d96 100644 --- a/cas-client-core/src/test/java/org/jasig/cas/client/validation/Cas20ProxyTicketValidatorTests.java +++ b/cas-client-core/src/test/java/org/jasig/cas/client/validation/Cas20ProxyTicketValidatorTests.java @@ -41,8 +41,9 @@ import static org.junit.Assert.*; * @version $Revision: 11737 $ $Date: 2007-10-03 09:14:02 -0400 (Tue, 03 Oct 2007) $ * @since 3.0 */ -public final class Cas20ProxyTicketValidatorTests extends - AbstractTicketValidatorTests { +public final class Cas20ProxyTicketValidatorTests extends AbstractTicketValidatorTests { + + private static final PublicTestHttpServer server = PublicTestHttpServer.instance(8089); private Cas20ProxyTicketValidator ticketValidator; @@ -52,7 +53,7 @@ public final class Cas20ProxyTicketValidatorTests extends @AfterClass public static void classCleanUp() { - PublicTestHttpServer.instance().shutdown(); + server.shutdown(); } @Before @@ -60,7 +61,7 @@ public final class Cas20ProxyTicketValidatorTests extends final List list = new ArrayList(); list.add(new String[] {"proxy1", "proxy2", "proxy3"}); - this.ticketValidator = new Cas20ProxyTicketValidator(CONST_CAS_SERVER_URL); + this.ticketValidator = new Cas20ProxyTicketValidator(CONST_CAS_SERVER_URL_PREFIX + "8089"); this.ticketValidator.setRenew(true); this.ticketValidator.setProxyCallbackUrl("test"); this.ticketValidator.setProxyGrantingTicketStorage(getProxyGrantingTicketStorage()); @@ -89,8 +90,7 @@ public final class Cas20ProxyTicketValidatorTests extends UnsupportedEncodingException { final String USERNAME = "username"; final String RESPONSE = "usernamePGTIOU-84678-8a9d...proxy1proxy2proxy3"; - PublicTestHttpServer.instance().content = RESPONSE - .getBytes(PublicTestHttpServer.instance().encoding); + server.content = RESPONSE.getBytes(server.encoding); final Assertion assertion = this.ticketValidator.validate("test", "test"); @@ -101,8 +101,7 @@ public final class Cas20ProxyTicketValidatorTests extends public void testProxyChainWithInvalidProxy() throws TicketValidationException, UnsupportedEncodingException { final String RESPONSE = "usernamePGTIOU-84678-8a9d...proxy7proxy2proxy3"; - PublicTestHttpServer.instance().content = RESPONSE - .getBytes(PublicTestHttpServer.instance().encoding); + server.content = RESPONSE.getBytes(server.encoding); try { this.ticketValidator.validate("test", "test"); @@ -113,18 +112,15 @@ public final class Cas20ProxyTicketValidatorTests extends } @Test - public void testConstructionFromSpringBean() throws TicketValidationException, - UnsupportedEncodingException { + public void testConstructionFromSpringBean() throws TicketValidationException, UnsupportedEncodingException { final ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:cas20ProxyTicketValidator.xml"); final Cas20ProxyTicketValidator v = (Cas20ProxyTicketValidator) context.getBean("proxyTicketValidator"); final String USERNAME = "username"; final String RESPONSE = "usernamePGTIOU-84678-8a9d...proxy1proxy2proxy3"; - PublicTestHttpServer.instance().content = RESPONSE - .getBytes(PublicTestHttpServer.instance().encoding); + server.content = RESPONSE.getBytes(server.encoding); - final Assertion assertion = v.validate("test", - "test"); + final Assertion assertion = v.validate("test","test"); assertEquals(USERNAME, assertion.getPrincipal().getName()); } diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/validation/Cas20ServiceTicketValidatorTests.java b/cas-client-core/src/test/java/org/jasig/cas/client/validation/Cas20ServiceTicketValidatorTests.java index 460a919..3963ee0 100644 --- a/cas-client-core/src/test/java/org/jasig/cas/client/validation/Cas20ServiceTicketValidatorTests.java +++ b/cas-client-core/src/test/java/org/jasig/cas/client/validation/Cas20ServiceTicketValidatorTests.java @@ -41,6 +41,8 @@ import java.io.UnsupportedEncodingException; */ public final class Cas20ServiceTicketValidatorTests extends AbstractTicketValidatorTests { + private static final PublicTestHttpServer server = PublicTestHttpServer.instance(8088); + private Cas20ServiceTicketValidator ticketValidator; private ProxyGrantingTicketStorage proxyGrantingTicketStorage; @@ -51,13 +53,13 @@ public final class Cas20ServiceTicketValidatorTests extends AbstractTicketValida @AfterClass public static void classCleanUp() { - PublicTestHttpServer.instance().shutdown(); + server.shutdown(); } @Before public void setUp() throws Exception { this.proxyGrantingTicketStorage = getProxyGrantingTicketStorage(); - this.ticketValidator = new Cas20ServiceTicketValidator(CONST_CAS_SERVER_URL); + this.ticketValidator = new Cas20ServiceTicketValidator(CONST_CAS_SERVER_URL_PREFIX + "8088"); this.ticketValidator.setProxyCallbackUrl("test"); this.ticketValidator.setProxyGrantingTicketStorage(getProxyGrantingTicketStorage()); this.ticketValidator.setProxyRetriever(getProxyRetriever()); @@ -83,8 +85,7 @@ public final class Cas20ServiceTicketValidatorTests extends AbstractTicketValida @Test public void testNoResponse() throws UnsupportedEncodingException { final String RESPONSE = "Ticket ST-1856339-aA5Yuvrxzpv8Tau1cYQ7 not recognized"; - PublicTestHttpServer.instance().content = RESPONSE - .getBytes(PublicTestHttpServer.instance().encoding); + server.content = RESPONSE.getBytes(server.encoding); try { this.ticketValidator.validate("test", "test"); fail("ValidationException expected due to 'no' response"); @@ -100,8 +101,7 @@ public final class Cas20ServiceTicketValidatorTests extends AbstractTicketValida final String RESPONSE = "" + USERNAME + ""; - PublicTestHttpServer.instance().content = RESPONSE - .getBytes(PublicTestHttpServer.instance().encoding); + server.content = RESPONSE.getBytes(server.encoding); final Assertion assertion = this.ticketValidator.validate("test", "test"); @@ -121,9 +121,7 @@ public final class Cas20ServiceTicketValidatorTests extends AbstractTicketValida + PGTIOU + ""; - PublicTestHttpServer.instance().content = RESPONSE - .getBytes(PublicTestHttpServer.instance().encoding); - + server.content = RESPONSE.getBytes(server.encoding); this.proxyGrantingTicketStorage.save(PGTIOU, PGT); final Assertion assertion = this.ticketValidator.validate("test", @@ -143,9 +141,7 @@ public final class Cas20ServiceTicketValidatorTests extends AbstractTicketValida + PGTIOU + "\ntest\nid\n"; - PublicTestHttpServer.instance().content = RESPONSE - .getBytes(PublicTestHttpServer.instance().encoding); - + server.content = RESPONSE.getBytes(server.encoding); final Assertion assertion = this.ticketValidator.validate("test", "test"); assertEquals(USERNAME, assertion.getPrincipal().getName()); assertEquals("test", assertion.getPrincipal().getAttributes().get("password")); @@ -156,8 +152,7 @@ public final class Cas20ServiceTicketValidatorTests extends AbstractTicketValida @Test public void testInvalidResponse() throws Exception { final String RESPONSE = ""; - PublicTestHttpServer.instance().content = RESPONSE - .getBytes(PublicTestHttpServer.instance().encoding); + server.content = RESPONSE.getBytes(server.encoding); try { this.ticketValidator.validate("test", "test"); fail("ValidationException expected due to invalid response."); diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/validation/Saml11TicketValidatorTests.java b/cas-client-core/src/test/java/org/jasig/cas/client/validation/Saml11TicketValidatorTests.java index f73a3ac..a18af94 100644 --- a/cas-client-core/src/test/java/org/jasig/cas/client/validation/Saml11TicketValidatorTests.java +++ b/cas-client-core/src/test/java/org/jasig/cas/client/validation/Saml11TicketValidatorTests.java @@ -21,6 +21,7 @@ package org.jasig.cas.client.validation; import org.jasig.cas.client.PublicTestHttpServer; import org.jasig.cas.client.util.CommonUtils; +import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.Test; @@ -39,15 +40,17 @@ public final class Saml11TicketValidatorTests extends AbstractTicketValidatorTes private Saml11TicketValidator validator; + private static final PublicTestHttpServer server = PublicTestHttpServer.instance(8087); + @Before public void setUp() throws Exception { - this.validator = new Saml11TicketValidator(CONST_CAS_SERVER_URL); + this.validator = new Saml11TicketValidator(CONST_CAS_SERVER_URL_PREFIX + "8087"); this.validator.setTolerance(1000L); } @AfterClass - public static void classCleanUp() { - PublicTestHttpServer.instance().shutdown(); + public static void cleanUp() throws Exception { + server.shutdown(); } @Test @@ -64,7 +67,7 @@ public final class Saml11TicketValidatorTests extends AbstractTicketValidatorTes " ResponseID=\"_3b62bece2e8da1c10279db04882012ac\">Success"; - PublicTestHttpServer.instance().content = RESPONSE.getBytes(PublicTestHttpServer.instance().encoding); + server.content = RESPONSE.getBytes(server.encoding); try { this.validator.validate("test", "test"); fail("ValidationException expected due to 'no' response"); @@ -79,7 +82,7 @@ public final class Saml11TicketValidatorTests extends AbstractTicketValidatorTes final Date before = new Date(now.getTime() - 5000); final Date after = new Date(now.getTime() + 200000000); final String RESPONSE = "testtestPrincipalurn:oasis:names:tc:SAML:1.0:cm:artifact"; - PublicTestHttpServer.instance().content = RESPONSE.getBytes(PublicTestHttpServer.instance().encoding); + server.content = RESPONSE.getBytes(server.encoding); try { final Assertion a = this.validator.validate("test", "test"); assertEquals("testPrincipal", a.getPrincipal().getName()); diff --git a/cas-client-core/src/test/resources/cas20ProxyTicketValidator.xml b/cas-client-core/src/test/resources/cas20ProxyTicketValidator.xml index 39f4c7c..3f38389 100644 --- a/cas-client-core/src/test/resources/cas20ProxyTicketValidator.xml +++ b/cas-client-core/src/test/resources/cas20ProxyTicketValidator.xml @@ -26,7 +26,7 @@ - + test test2 test3 test4 test5 @@ -41,6 +41,6 @@ - + \ No newline at end of file diff --git a/cas-client-support-distributed-ehcache/pom.xml b/cas-client-support-distributed-ehcache/pom.xml index 71600c9..4224f6a 100644 --- a/cas-client-support-distributed-ehcache/pom.xml +++ b/cas-client-support-distributed-ehcache/pom.xml @@ -29,6 +29,13 @@ jar + + org.slf4j + slf4j-api + 1.6.1 + test + + \ No newline at end of file diff --git a/cas-client-support-distributed-ehcache/src/main/java/org/jasig/cas/client/proxy/EhcacheBackedProxyGrantingTicketStorageImpl.java b/cas-client-support-distributed-ehcache/src/main/java/org/jasig/cas/client/proxy/EhcacheBackedProxyGrantingTicketStorageImpl.java index c78491f..7e95ded 100644 --- a/cas-client-support-distributed-ehcache/src/main/java/org/jasig/cas/client/proxy/EhcacheBackedProxyGrantingTicketStorageImpl.java +++ b/cas-client-support-distributed-ehcache/src/main/java/org/jasig/cas/client/proxy/EhcacheBackedProxyGrantingTicketStorageImpl.java @@ -26,12 +26,16 @@ import net.sf.ehcache.distribution.RemoteCacheException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.spec.InvalidKeySpecException; + /** * @author Scott Battaglia * @version $Revision$ $Date$ * @since 3.1.9 */ -public final class EhcacheBackedProxyGrantingTicketStorageImpl implements ProxyGrantingTicketStorage { +public final class EhcacheBackedProxyGrantingTicketStorageImpl extends AbstractEncryptedProxyGrantingTicketStorageImpl { public static final String EHCACHE_CACHE_NAME = "org.jasig.cas.client.proxy.EhcacheBackedProxyGrantingTicketStorageImpl.cache"; @@ -45,11 +49,15 @@ public final class EhcacheBackedProxyGrantingTicketStorageImpl implements ProxyG } public EhcacheBackedProxyGrantingTicketStorageImpl(final Cache cache) { + super(); this.cache = cache; - } - public void save(final String proxyGrantingTicketIou, final String proxyGrantingTicket) { + public EhcacheBackedProxyGrantingTicketStorageImpl(final String secret) throws NoSuchAlgorithmException, InvalidKeyException, InvalidKeySpecException { + this.cache = CacheManager.getInstance().getCache(EHCACHE_CACHE_NAME); + } + + public void saveInternal(final String proxyGrantingTicketIou, final String proxyGrantingTicket) { final Element element = new Element(proxyGrantingTicketIou, proxyGrantingTicket); try { this.cache.put(element); @@ -58,7 +66,7 @@ public final class EhcacheBackedProxyGrantingTicketStorageImpl implements ProxyG } } - public String retrieve(final String proxyGrantingTicketIou) { + public String retrieveInternal(final String proxyGrantingTicketIou) { final Element element = this.cache.get(proxyGrantingTicketIou); if (element == null) { diff --git a/cas-client-support-distributed-ehcache/src/test/java/EhCacheBackedProxyGrantingTicketStorageImplTests.java b/cas-client-support-distributed-ehcache/src/test/java/EhCacheBackedProxyGrantingTicketStorageImplTests.java new file mode 100644 index 0000000..41cb7a3 --- /dev/null +++ b/cas-client-support-distributed-ehcache/src/test/java/EhCacheBackedProxyGrantingTicketStorageImplTests.java @@ -0,0 +1,27 @@ +import junit.framework.TestCase; +import net.sf.ehcache.Cache; +import net.sf.ehcache.CacheManager; +import net.sf.ehcache.Ehcache; +import org.jasig.cas.client.proxy.EhcacheBackedProxyGrantingTicketStorageImpl; + +/** + * @author Scott Battaglia + * @version $Revision$ $Date$ + * @since 3.2.0 + */ +public class EhCacheBackedProxyGrantingTicketStorageImplTests extends TestCase { + + public void testEncryptionMechanisms() throws Exception { + final Cache ehcache = new Cache("name", 100,false, false, 500, 500); + CacheManager.getInstance().addCache(ehcache); + final EhcacheBackedProxyGrantingTicketStorageImpl cache = new EhcacheBackedProxyGrantingTicketStorageImpl(ehcache); + cache.setSecretKey("thismustbeatleast24charactersandcannotbelessthanthat"); + + assertNull(cache.retrieve(null)); + assertNull(cache.retrieve("foobar")); + + cache.save("proxyGrantingTicketIou", "proxyGrantingTicket"); + assertEquals("proxyGrantingTicket", cache.retrieve("proxyGrantingTicketIou")); + assertFalse("proxyGrantingTicket".equals(ehcache.get("proxyGrantingTicketIou").getValue())); + } +} diff --git a/cas-client-support-distributed-memcached/src/main/java/org/jasig/cas/client/proxy/MemcachedBackedProxyGrantingTicketStorageImpl.java b/cas-client-support-distributed-memcached/src/main/java/org/jasig/cas/client/proxy/MemcachedBackedProxyGrantingTicketStorageImpl.java index c50e0c7..910eb8e 100644 --- a/cas-client-support-distributed-memcached/src/main/java/org/jasig/cas/client/proxy/MemcachedBackedProxyGrantingTicketStorageImpl.java +++ b/cas-client-support-distributed-memcached/src/main/java/org/jasig/cas/client/proxy/MemcachedBackedProxyGrantingTicketStorageImpl.java @@ -35,7 +35,7 @@ import java.util.concurrent.Future; * @version $Revision$ $Date$ * @since 3.1.9 */ -public final class MemcachedBackedProxyGrantingTicketStorageImpl implements ProxyGrantingTicketStorage { +public final class MemcachedBackedProxyGrantingTicketStorageImpl extends AbstractEncryptedProxyGrantingTicketStorageImpl { private final MemcachedClient client; @@ -92,11 +92,11 @@ public final class MemcachedBackedProxyGrantingTicketStorageImpl implements Prox } - public void save(final String proxyGrantingTicketIou, final String proxyGrantingTicket) { + public void saveInternal(final String proxyGrantingTicketIou, final String proxyGrantingTicket) { handleSynchronousRequest(this.client.add(proxyGrantingTicketIou, 120, proxyGrantingTicket)); } - public String retrieve(final String proxyGrantingTicketIou) { + public String retrieveInternal(final String proxyGrantingTicketIou) { return (String) this.client.get(proxyGrantingTicketIou); }