You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by iv...@apache.org on 2009/04/17 19:37:37 UTC
svn commit: r766095 - in
/wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/https: ./
HttpsConfig.java HttpsRequestCycleProcessor.java RequireHttps.java
SwitchProtocolRequestTarget.java
Author: ivaynberg
Date: Fri Apr 17 17:37:36 2009
New Revision: 766095
URL: http://svn.apache.org/viewvc?rev=766095&view=rev
Log:
https/http switching support, WICKET-2229
Issue: WICKET-2229
Added:
wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/https/
wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/https/HttpsConfig.java (with props)
wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/https/HttpsRequestCycleProcessor.java (with props)
wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/https/RequireHttps.java (with props)
wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/https/SwitchProtocolRequestTarget.java (with props)
Added: wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/https/HttpsConfig.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/https/HttpsConfig.java?rev=766095&view=auto
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/https/HttpsConfig.java (added)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/https/HttpsConfig.java Fri Apr 17 17:37:36 2009
@@ -0,0 +1,87 @@
+/*
+ * 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.wicket.protocol.https;
+
+/**
+ * Configuration for http-https switching
+ *
+ * @see HttpsRequestCycleProcessor
+ */
+public class HttpsConfig
+{
+ private int httpPort = 80;
+ private int httpsPort = 443;
+
+ /**
+ * Constructor
+ */
+ public HttpsConfig()
+ {
+
+ }
+
+ /**
+ * Constructor
+ *
+ * @param httpPort
+ * http port
+ * @param httpsPort
+ * https port
+ */
+ public HttpsConfig(int httpPort, int httpsPort)
+ {
+ this.httpPort = httpPort;
+ this.httpsPort = httpsPort;
+ }
+
+
+ /**
+ * Sets http port
+ *
+ * @param httpPort
+ */
+ public void setHttpPort(int httpPort)
+ {
+ this.httpPort = httpPort;
+ }
+
+ /**
+ * Sets https port
+ *
+ * @param httpsPort
+ */
+ public void setHttpsPort(int httpsPort)
+ {
+ this.httpsPort = httpsPort;
+ }
+
+ /**
+ * @return http port
+ */
+ public int getHttpPort()
+ {
+ return httpPort;
+ }
+
+ /**
+ * @return https port
+ */
+ public int getHttpsPort()
+ {
+ return httpsPort;
+ }
+}
Propchange: wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/https/HttpsConfig.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/https/HttpsRequestCycleProcessor.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/https/HttpsRequestCycleProcessor.java?rev=766095&view=auto
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/https/HttpsRequestCycleProcessor.java (added)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/https/HttpsRequestCycleProcessor.java Fri Apr 17 17:37:36 2009
@@ -0,0 +1,163 @@
+/*
+ * 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.wicket.protocol.https;
+
+import org.apache.wicket.IRequestTarget;
+import org.apache.wicket.RequestCycle;
+import org.apache.wicket.Session;
+import org.apache.wicket.protocol.http.WebRequestCycleProcessor;
+import org.apache.wicket.protocol.https.SwitchProtocolRequestTarget.Protocol;
+import org.apache.wicket.request.RequestParameters;
+import org.apache.wicket.request.target.component.IBookmarkablePageRequestTarget;
+import org.apache.wicket.request.target.component.IPageRequestTarget;
+
+
+/**
+ * Request cycle processor that can switch between http and https protocols based on the
+ * {@link RequireHttps} annotation.
+ *
+ * Once this processor is installed, any page annotated with the {@link RequireHttps} annotation
+ * will be served over https, while any page lacking the annotation will be served over http. The
+ * annotation can be placed on a super class or an interface that a page implements.
+ *
+ * To install this processor:
+ *
+ * <pre>
+ * class MyApplication extends WebApplication
+ * {
+ * @Override
+ * protected IRequestCycleProcessor newRequestCycleProcessor()
+ * {
+ * return new SecureRequestCycleProcessor(config);
+ * }
+ * }
+ * </pre>
+ *
+ * <b>Notes</b>: According to servlet spec a cookie created on an https request is marked as secure,
+ * such cookies are not available for http requests. What this means is that a session started over
+ * https will not be propagated to further http calls because JSESSIONID cookie will be marked as
+ * secure and not available to http requests. This entails that unless a session is created and
+ * bound on http prior to using an https request any wicket pages or session values stored in the
+ * https session will not be available to further http requests. If your application requires a
+ * http->https->http interactions (such as the case where only a login page and my account
+ * pages are secure) you must make sure a session is created and stored in the http request prior to
+ * the first http->https redirect.
+ */
+public class HttpsRequestCycleProcessor extends WebRequestCycleProcessor
+{
+ private final HttpsConfig portConfig;
+
+ /**
+ * Constructor
+ *
+ * @param httpsConfig
+ * configuration
+ */
+ public HttpsRequestCycleProcessor(HttpsConfig httpsConfig)
+ {
+ portConfig = httpsConfig;
+ }
+
+ /**
+ * @return configuration
+ */
+ public HttpsConfig getConfig()
+ {
+ return portConfig;
+ }
+
+ /**
+ * Checks if the class has a {@link RequireHttps} annotation
+ *
+ * @param klass
+ * @return true if klass has the annotation
+ */
+ private boolean hasSecureAnnotation(Class<?> klass)
+ {
+ for (Class<?> c : klass.getInterfaces())
+ {
+ if (hasSecureAnnotation(c))
+ {
+ return true;
+ }
+ }
+ if (klass.getAnnotation(RequireHttps.class) != null)
+ {
+ return true;
+ }
+ if (klass.getSuperclass() != null)
+ {
+ return hasSecureAnnotation(klass.getSuperclass());
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Gets page class from a request target
+ *
+ * @param target
+ * @return page class if there is one, null otherwise
+ */
+ private Class<?> getPageClass(IRequestTarget target)
+ {
+ if (target instanceof IPageRequestTarget)
+ {
+ return ((IPageRequestTarget)target).getPage().getClass();
+ }
+ else if (target instanceof IBookmarkablePageRequestTarget)
+ {
+ return ((IBookmarkablePageRequestTarget)target).getPageClass();
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public IRequestTarget resolve(RequestCycle rc, RequestParameters rp)
+ {
+ // we need to persist the session before a redirect to https so the session lasts across
+ // both http and https calls.
+ Session.get().bind();
+
+ IRequestTarget target = super.resolve(rc, rp);
+ Class<?> pageClass = getPageClass(target);
+ if (pageClass != null)
+ {
+ IRequestTarget redirect = null;
+ if (hasSecureAnnotation(pageClass))
+ {
+ redirect = SwitchProtocolRequestTarget.requireProtocol(Protocol.HTTPS);
+ }
+ else
+ {
+ redirect = SwitchProtocolRequestTarget.requireProtocol(Protocol.HTTP);
+ }
+ if (redirect != null)
+ {
+ return redirect;
+ }
+
+ }
+ return target;
+ }
+}
Propchange: wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/https/HttpsRequestCycleProcessor.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/https/RequireHttps.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/https/RequireHttps.java?rev=766095&view=auto
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/https/RequireHttps.java (added)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/https/RequireHttps.java Fri Apr 17 17:37:36 2009
@@ -0,0 +1,34 @@
+/*
+ * 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.wicket.protocol.https;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Marks a page as requiring https.
+ *
+ * @see HttpsRequestCycleProcessor
+ *
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface RequireHttps {
+
+}
Propchange: wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/https/RequireHttps.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/https/SwitchProtocolRequestTarget.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/https/SwitchProtocolRequestTarget.java?rev=766095&view=auto
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/https/SwitchProtocolRequestTarget.java (added)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/https/SwitchProtocolRequestTarget.java Fri Apr 17 17:37:36 2009
@@ -0,0 +1,162 @@
+/*
+ * 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.wicket.protocol.https;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.wicket.IRequestTarget;
+import org.apache.wicket.RequestCycle;
+import org.apache.wicket.protocol.http.WebRequest;
+import org.apache.wicket.protocol.http.WebResponse;
+
+/**
+ * Request target that performs redirects across http and https
+ */
+class SwitchProtocolRequestTarget implements IRequestTarget
+{
+ /**
+ * Protocols
+ */
+ public enum Protocol {
+ /*** HTTP */
+ HTTP,
+ /** HTTPS */
+ HTTPS,
+ /** CURRENT */
+ PRESERVE_CURRENT
+ }
+
+ private final Protocol protocol;
+
+ /**
+ * Constructor
+ *
+ * @param protocol
+ * required protocol
+ */
+ public SwitchProtocolRequestTarget(Protocol protocol)
+ {
+ if (protocol == null)
+ {
+ throw new IllegalArgumentException("Argument 'protocol' may not be null.");
+ }
+ if (protocol == Protocol.PRESERVE_CURRENT)
+ {
+ throw new IllegalArgumentException("Argument 'protocol' may not have value '" +
+ Protocol.PRESERVE_CURRENT.toString() + "'.");
+ }
+ this.protocol = protocol;
+ }
+
+ /** {@inheritDoc} */
+ public void detach(RequestCycle requestCycle)
+ {
+
+ }
+
+ /**
+ * Rewrite the url using the specified protocol
+ *
+ * @param protocol
+ * @param port
+ * @param request
+ * @return url
+ */
+ private String getUrl(String protocol, Integer port, HttpServletRequest request)
+ {
+ StringBuilder result = new StringBuilder();
+ result.append(protocol);
+ result.append("://");
+ result.append(request.getServerName());
+ if (port != null)
+ {
+ result.append(":");
+ result.append(port);
+ }
+ result.append(request.getRequestURI());
+ if (request.getQueryString() != null)
+ {
+ result.append("?");
+ result.append(request.getQueryString());
+ }
+ return result.toString();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void respond(RequestCycle requestCycle)
+ {
+ WebRequest webRequest = (WebRequest)requestCycle.getRequest();
+ HttpServletRequest request = webRequest.getHttpServletRequest();
+
+ HttpsRequestCycleProcessor processor = (HttpsRequestCycleProcessor)requestCycle.getProcessor();
+ Integer port = null;
+ if (protocol == Protocol.HTTP)
+ {
+ if (processor.getConfig().getHttpPort() != 80)
+ {
+ port = processor.getConfig().getHttpPort();
+ }
+ }
+ else if (protocol == Protocol.HTTPS)
+ {
+ if (processor.getConfig().getHttpsPort() != 443)
+ {
+ port = processor.getConfig().getHttpsPort();
+ }
+ }
+
+ String url = getUrl(protocol.toString().toLowerCase(), port, request);
+
+ WebResponse response = (WebResponse)requestCycle.getResponse();
+
+ // an attempt to rewrite a secure jsessionid into nonsecure, doesnt seem to work
+ // Session session = Session.get();
+ // if (!session.isTemporary())
+ // {
+ // response.addCookie(new Cookie("JSESSIONID", session.getId()));
+ // }
+
+ response.redirect(url);
+ }
+
+ /**
+ * Returns a target that can be used to redirect to the specified protocol. If no change is
+ * required null will be returned.
+ *
+ * @param protocol
+ * required protocol
+ * @return request target or null
+ */
+ public static IRequestTarget requireProtocol(Protocol protocol)
+ {
+ RequestCycle requestCycle = RequestCycle.get();
+ WebRequest webRequest = (WebRequest)requestCycle.getRequest();
+ HttpServletRequest request = webRequest.getHttpServletRequest();
+ if (protocol == null || protocol == Protocol.PRESERVE_CURRENT ||
+ request.getScheme().equals(protocol.toString().toLowerCase()))
+ {
+ return null;
+ }
+ else
+ {
+ return new SwitchProtocolRequestTarget(protocol);
+ }
+ }
+
+}
Propchange: wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/https/SwitchProtocolRequestTarget.java
------------------------------------------------------------------------------
svn:mime-type = text/plain