You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shindig.apache.org by rb...@apache.org on 2011/11/02 17:57:17 UTC

svn commit: r1196683 - in /shindig/trunk: config/container.js java/common/src/main/java/org/apache/shindig/auth/BlobCrypterSecurityTokenCodec.java java/common/src/test/java/org/apache/shindig/auth/BlobCrypterSecurityTokenCodecTest.java

Author: rbaxter85
Date: Wed Nov  2 16:57:16 2011
New Revision: 1196683

URL: http://svn.apache.org/viewvc?rev=1196683&view=rev
Log:
SHINDIG-1636
Committed for Stanton Sievers
Allow the blob crypter encryption key to be provided explicitly in the config

Modified:
    shindig/trunk/config/container.js
    shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/BlobCrypterSecurityTokenCodec.java
    shindig/trunk/java/common/src/test/java/org/apache/shindig/auth/BlobCrypterSecurityTokenCodecTest.java

Modified: shindig/trunk/config/container.js
URL: http://svn.apache.org/viewvc/shindig/trunk/config/container.js?rev=1196683&r1=1196682&r2=1196683&view=diff
==============================================================================
--- shindig/trunk/config/container.js (original)
+++ shindig/trunk/config/container.js Wed Nov  2 16:57:16 2011
@@ -96,10 +96,14 @@
 // substituted with the current host.
 "gadgets.osDataUri" : "http://%host%${CONTEXT_ROOT}/rpc",
 
-// Uncomment these to switch to a secure version
+// Uncomment these to switch to a secure version. If both a key file and key are provided, the key
+// will take precedence; thus, to use a key file, you must explicitly not provide a key. The
+// best way to generate a key is to do something like this:
+// dd if=/dev/random bs=32 count=1 | openssl base64
 //
-//"gadgets.securityTokenType" : "secure",
-//"gadgets.securityTokenKeyFile" : "/path/to/key/file.txt",
+// "gadgets.securityTokenType" : "secure",
+// "gadgets.securityTokenKeyFile" : "/path/to/key/file.txt",
+// "gadgets.securityTokenKey" : "",
 
 // OS 2.0 Gadget DOCTYPE: used in Gadgets with @specificationVersion 2.0 or greater and
 // quirksmode on Gadget has not been set.

Modified: shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/BlobCrypterSecurityTokenCodec.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/BlobCrypterSecurityTokenCodec.java?rev=1196683&r1=1196682&r2=1196683&view=diff
==============================================================================
--- shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/BlobCrypterSecurityTokenCodec.java (original)
+++ shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/BlobCrypterSecurityTokenCodec.java Wed Nov  2 16:57:16 2011
@@ -32,6 +32,7 @@ import org.apache.shindig.common.crypto.
 import org.apache.shindig.common.util.ResourceLoader;
 import org.apache.shindig.config.ContainerConfig;
 
+import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.Maps;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
@@ -57,6 +58,8 @@ public class BlobCrypterSecurityTokenCod
 
   public static final String SECURITY_TOKEN_KEY_FILE = "gadgets.securityTokenKeyFile";
 
+  public static final String SECURITY_TOKEN_KEY = "gadgets.securityTokenKey";
+
   public static final String SIGNED_FETCH_DOMAIN = "gadgets.signedFetchDomain";
 
   /**
@@ -107,8 +110,12 @@ public class BlobCrypterSecurityTokenCod
       Map<String, BlobCrypter> crypters, Map<String, String> domains) throws IOException {
     for (String container : containers) {
       String keyFile = config.getString(container, SECURITY_TOKEN_KEY_FILE);
-      if (keyFile != null) {
-        BlobCrypter crypter = loadCrypter(keyFile);
+      String key = config.getString(container, SECURITY_TOKEN_KEY);
+      if (key != null) {
+        BlobCrypter crypter = loadCrypter(key);
+        crypters.put(container, crypter);
+      } else if (keyFile != null) {
+        BlobCrypter crypter = loadCrypter(getKeyFromFile(keyFile));
         crypters.put(container, crypter);
       }
       String domain = config.getString(container, SIGNED_FETCH_DOMAIN);
@@ -117,16 +124,27 @@ public class BlobCrypterSecurityTokenCod
   }
 
   /**
+   * Gets a key from the given keyFile.
+   *
+   * @param keyFile the key file from which to read the key
+   * @return the key
+   * @throws IOException if there was an error read the key file
+   */
+  @VisibleForTesting
+  protected String getKeyFromFile(String keyFile) throws IOException {
+    return IOUtils.toString(ResourceLoader.open(keyFile), "UTF-8");
+  }
+
+  /**
    * Load a BlobCrypter from the key file.  Override this if you have your own
    * BlobCrypter implementation.
    *
-   * @param keyFile The key file to load from.  This can either be an absolute file path or a
-   * reference to a resource that should be loaded from the classpath (ie res://key-file.txt).
+   * @param key The key to use for encryption
    * @return The BlobCrypter.
    * @throws IOException If the key file is invalid.
    */
-  protected BlobCrypter loadCrypter(String keyFile) throws IOException {
-    return new BasicBlobCrypter(IOUtils.toString(ResourceLoader.open(keyFile), "UTF-8"));
+  protected BlobCrypter loadCrypter(String key) throws IOException {
+    return new BasicBlobCrypter(key);
   }
 
   /**

Modified: shindig/trunk/java/common/src/test/java/org/apache/shindig/auth/BlobCrypterSecurityTokenCodecTest.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/common/src/test/java/org/apache/shindig/auth/BlobCrypterSecurityTokenCodecTest.java?rev=1196683&r1=1196682&r2=1196683&view=diff
==============================================================================
--- shindig/trunk/java/common/src/test/java/org/apache/shindig/auth/BlobCrypterSecurityTokenCodecTest.java (original)
+++ shindig/trunk/java/common/src/test/java/org/apache/shindig/auth/BlobCrypterSecurityTokenCodecTest.java Wed Nov  2 16:57:16 2011
@@ -56,18 +56,34 @@ public class BlobCrypterSecurityTokenCod
         .addContainer(makeContainer("default"))
         .addContainer(makeContainer("container"))
         .addContainer(makeContainer("example"))
+        .addContainer(makeContainer("keyOnlyNoFile", true))
         .commit();
     codec = new CodecWithLoadStubbedOut(config);
     timeSource = new FakeTimeSource();
   }
 
   protected Map<String, Object> makeContainer(String container) {
-    return ImmutableMap.<String, Object>of(ContainerConfig.CONTAINER_KEY,
-        ImmutableList.of(container),
-        BlobCrypterSecurityTokenCodec.SECURITY_TOKEN_KEY_FILE,
-        getContainerKey(container),
-        BlobCrypterSecurityTokenCodec.SIGNED_FETCH_DOMAIN,
-        container + ".com");
+    return makeContainer(container, false);
+  }
+
+  protected Map<String, Object> makeContainer(String container, boolean insertKey) {
+    if (insertKey) {
+      return ImmutableMap.<String, Object>of(ContainerConfig.CONTAINER_KEY,
+          ImmutableList.of(container),
+          BlobCrypterSecurityTokenCodec.SECURITY_TOKEN_KEY_FILE,
+          container,
+          BlobCrypterSecurityTokenCodec.SECURITY_TOKEN_KEY,
+          getContainerKey(container),
+          BlobCrypterSecurityTokenCodec.SIGNED_FETCH_DOMAIN,
+          container + ".com");
+    } else {
+      return ImmutableMap.<String, Object>of(ContainerConfig.CONTAINER_KEY,
+              ImmutableList.of(container),
+              BlobCrypterSecurityTokenCodec.SECURITY_TOKEN_KEY_FILE,
+              container,
+              BlobCrypterSecurityTokenCodec.SIGNED_FETCH_DOMAIN,
+              container + ".com");
+    }
   }
 
   protected String getContainerKey(String container) {
@@ -95,16 +111,16 @@ public class BlobCrypterSecurityTokenCod
      * @throws IOException when passed a filename with 'fail' in it.
      */
     @Override
-    protected BlobCrypter loadCrypter(String file) throws IOException {
+    protected String getKeyFromFile(String file) throws IOException {
       if (file.contains("fail")) {
         throw new IOException("Load failed: " + file);
       }
-      return getBlobCrypter(file);
+      return getContainerKey(file);
     }
   }
 
   @Test
-  public void testCreateToken() throws Exception {
+  public void testCreateTokenUsingKeyFile() throws Exception {
     Map<String, String> values = new HashMap<String, String>();
     values.put(Keys.APP_URL.getKey(), "http://www.example.com/gadget.xml");
     values.put(Keys.MODULE_ID.getKey(), Long.toString(12345L, 10));
@@ -254,4 +270,27 @@ public class BlobCrypterSecurityTokenCod
       // pass
     }
   }
+
+  @Test
+  public void testCreateTokenUsingKey() throws Exception {
+    Map<String, String> values = new HashMap<String, String>();
+    values.put(Keys.APP_URL.getKey(), "http://www.example.com/gadget.xml");
+    values.put(Keys.MODULE_ID.getKey(), Long.toString(12345L, 10));
+    values.put(Keys.OWNER.getKey(), "owner");
+    values.put(Keys.VIEWER.getKey(), "viewer");
+    values.put(Keys.TRUSTED_JSON.getKey(), "trusted");
+
+    BlobCrypterSecurityToken t = new BlobCrypterSecurityToken("keyOnlyNoFile", null, null, values);
+    String encrypted = t.getContainer() + ":" + getBlobCrypter(getContainerKey("keyOnlyNoFile")).wrap(t.toMap());
+
+    SecurityToken t2 = codec.createToken(ImmutableMap.of(SecurityTokenCodec.SECURITY_TOKEN_NAME, encrypted));
+
+    assertEquals("http://www.example.com/gadget.xml", t2.getAppId());
+    assertEquals("http://www.example.com/gadget.xml", t2.getAppUrl());
+    assertEquals("keyOnlyNoFile.com", t2.getDomain());
+    assertEquals(12345L, t2.getModuleId());
+    assertEquals("owner", t2.getOwnerId());
+    assertEquals("viewer", t2.getViewerId());
+    assertEquals("trusted", t2.getTrustedJson());
+  }
 }