Add setting to throw PageExpiredException when encrypted URL is no longer
decryptable
(cherry picked from commit 88ef25b6ab7f94c7e9e4bfe2e5787072f2f7cf89)
Conflicts:
wicket-core/src/main/java/org/apache/wicket/core/request/mapper/CryptoMapper.java
Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/997581d9
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/997581d9
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/997581d9
Branch: refs/heads/master
Commit: 997581d970c68789f7e0f9775a52404fdf1cde8e
Parents: ded3c58
Author: Jesse Long <[email protected]>
Authored: Thu Oct 9 17:32:22 2014 +0200
Committer: Jesse Long <[email protected]>
Committed: Wed Oct 15 00:06:03 2014 +0200
----------------------------------------------------------------------
.../core/request/mapper/CryptoMapper.java | 71 +++++++++++++++++++-
.../core/request/mapper/CryptoMapperTest.java | 28 ++++++++
2 files changed, 97 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/wicket/blob/997581d9/wicket-core/src/main/java/org/apache/wicket/core/request/mapper/CryptoMapper.java
----------------------------------------------------------------------
diff --git
a/wicket-core/src/main/java/org/apache/wicket/core/request/mapper/CryptoMapper.java
b/wicket-core/src/main/java/org/apache/wicket/core/request/mapper/CryptoMapper.java
index 99f7afc..1c8933d 100755
---
a/wicket-core/src/main/java/org/apache/wicket/core/request/mapper/CryptoMapper.java
+++
b/wicket-core/src/main/java/org/apache/wicket/core/request/mapper/CryptoMapper.java
@@ -21,6 +21,7 @@ import java.util.List;
import org.apache.wicket.Application;
import org.apache.wicket.core.request.handler.RequestSettingRequestHandler;
+import org.apache.wicket.protocol.http.PageExpiredException;
import org.apache.wicket.request.IRequestHandler;
import org.apache.wicket.request.IRequestMapper;
import org.apache.wicket.request.Request;
@@ -69,6 +70,12 @@ import org.slf4j.LoggerFactory;
* When encrypting mounted URLs, we look for the {@link PageComponentInfo}
parameter, and encrypt only that parameter.
* </p>
*
+ * <p>
+ * {@link CryptoMapper} can be configured to mark encrypted URLs as encrypted,
and throw a {@link PageExpiredException}
+ * exception if a encrypted URL cannot be decrypted. This can occur when using
{@code KeyInSessionSubJceCryptFactory}, and
+ * the session has expired.
+ * </p>
+ *
* @author igor.vaynberg
* @author Jesse Long
* @author svenmeier
@@ -82,10 +89,17 @@ public class CryptoMapper implements IRequestMapperDelegate
*/
private static final String ENCRYPTED_PAGE_COMPONENT_INFO_PARAMETER =
"wicket";
+ private static final String ENCRYPTED_URL_MARKER_PREFIX = "crypt.";
+
private final IRequestMapper wrappedMapper;
private final IProvider<ICrypt> cryptProvider;
/**
+ * Whether or not to mark encrypted URLs as encrypted.
+ */
+ private boolean markEncryptedUrls = false;
+
+ /**
* Encrypt with {@link
org.apache.wicket.settings.SecuritySettings#getCryptFactory()}.
* <p>
* Note: Encryption is done with {@link
org.apache.wicket.settings.SecuritySettings#DEFAULT_ENCRYPTION_KEY}
@@ -117,6 +131,32 @@ public class CryptoMapper implements IRequestMapperDelegate
}
/**
+ * Whether or not to mark encrypted URLs as encrypted. If set, a {@link
PageExpiredException} is thrown when
+ * a encrypted URL can no longer be decrypted.
+ *
+ * @return whether or not to mark encrypted URLs as encrypted.
+ */
+ public boolean getMarkEncryptedUrls()
+ {
+ return markEncryptedUrls;
+ }
+
+ /**
+ * Sets whether or not to mark encrypted URLs as encrypted. If set, a
{@link PageExpiredException} is thrown when
+ * a encrypted URL can no longer be decrypted.
+ *
+ * @param markEncryptedUrls
+ * whether or not to mark encrypted URLs as encrypted.
+ *
+ * @return {@code this}, for chaining.
+ */
+ public CryptoMapper setMarkEncryptedUrls(boolean markEncryptedUrls)
+ {
+ this.markEncryptedUrls = markEncryptedUrls;
+ return this;
+ }
+
+ /**
* {@inheritDoc}
* <p>
* This implementation decrypts the URL and passes the decrypted URL to
the wrapped mapper.
@@ -241,7 +281,15 @@ public class CryptoMapper implements IRequestMapperDelegate
String encryptedUrlString =
getCrypt().encryptUrlSafe(url.toString());
Url encryptedUrl = new Url(url.getCharset());
- encryptedUrl.getSegments().add(encryptedUrlString);
+
+ if (getMarkEncryptedUrls())
+ {
+
encryptedUrl.getSegments().add(ENCRYPTED_URL_MARKER_PREFIX +
encryptedUrlString);
+ }
+ else
+ {
+ encryptedUrl.getSegments().add(encryptedUrlString);
+ }
int numberOfSegments = url.getSegments().size() - 1;
HashedSegmentGenerator generator = new
HashedSegmentGenerator(encryptedUrlString);
@@ -361,6 +409,18 @@ public class CryptoMapper implements IRequestMapperDelegate
return null;
}
+ if (getMarkEncryptedUrls())
+ {
+ if
(encryptedUrlString.startsWith(ENCRYPTED_URL_MARKER_PREFIX))
+ {
+ encryptedUrlString =
encryptedUrlString.substring(ENCRYPTED_URL_MARKER_PREFIX.length());
+ }
+ else
+ {
+ return null;
+ }
+ }
+
String decryptedUrl;
try
{
@@ -374,7 +434,14 @@ public class CryptoMapper implements IRequestMapperDelegate
if (decryptedUrl == null)
{
- return null;
+ if (getMarkEncryptedUrls())
+ {
+ throw new PageExpiredException("Encrypted URL
is no longer decryptable");
+ }
+ else
+ {
+ return null;
+ }
}
Url originalUrl = Url.parse(decryptedUrl, request.getCharset());
http://git-wip-us.apache.org/repos/asf/wicket/blob/997581d9/wicket-core/src/test/java/org/apache/wicket/core/request/mapper/CryptoMapperTest.java
----------------------------------------------------------------------
diff --git
a/wicket-core/src/test/java/org/apache/wicket/core/request/mapper/CryptoMapperTest.java
b/wicket-core/src/test/java/org/apache/wicket/core/request/mapper/CryptoMapperTest.java
index 1f7ecad..7b2cd4d 100644
---
a/wicket-core/src/test/java/org/apache/wicket/core/request/mapper/CryptoMapperTest.java
+++
b/wicket-core/src/test/java/org/apache/wicket/core/request/mapper/CryptoMapperTest.java
@@ -29,6 +29,7 @@ import org.apache.wicket.markup.IMarkupFragment;
import org.apache.wicket.markup.Markup;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.link.ILinkListener;
+import org.apache.wicket.protocol.http.PageExpiredException;
import org.apache.wicket.protocol.http.WebApplication;
import org.apache.wicket.request.IRequestHandler;
import org.apache.wicket.request.IRequestHandlerDelegate;
@@ -598,6 +599,33 @@ public class CryptoMapperTest extends AbstractMapperTest
.toString());
}
+ @Test
+ public void markedEncryptedUrlDecrypt()
+ {
+ mapper.setMarkEncryptedUrls(true);
+ Request request = getRequest(Url.parse("crypt." +
ENCRYPTED_BOOKMARKABLE_URL));
+ IRequestHandler requestHandler = mapper.mapRequest(request);
+
+ assertNotNull(requestHandler);
+ requestHandler = unwrapRequestHandlerDelegate(requestHandler);
+
+ assertTrue(requestHandler instanceof RenderPageRequestHandler);
+
+ RenderPageRequestHandler handler = (RenderPageRequestHandler)
requestHandler;
+ assertEquals(Page2.class, handler.getPageClass());
+ }
+
+ @Test(expected = PageExpiredException.class)
+ public void expiredMarkedEncryptedUrlThrowsPageExpiredException()
+ {
+ mapper.setMarkEncryptedUrls(true);
+ Url encryptedUrl = mapper.mapHandler(new
RenderPageRequestHandler(new PageProvider(Page2.class)));
+
assertTrue(encryptedUrl.getSegments().get(0).startsWith("crypt."));
+ encryptedUrl.getSegments().remove(0);
+ encryptedUrl.getSegments().add(0, "crypt.no decryptable");
+ mapper.mapRequest(getRequest(encryptedUrl));
+ }
+
private static IRequestHandler
unwrapRequestHandlerDelegate(IRequestHandler handler)
{
while (handler instanceof IRequestHandlerDelegate)