Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: declarative web.xml-settings for the entire application

...

Panel
borderStylesolid
titleTable of contents
Table of Contents
minLevel3

For The Entire Application

Code Block
xml
xml
titleweb.xml

<web-app ...>
   <security-constraint>
      <user-data-constraint>
         <transport-guarantee>CONFIDENTIAL</transport-guarantee>
      </user-data-constraint>
   </security-constraint>
</web-app>

Quote from web-app_2_3.dtd:

The transport-guarantee element specifies that the communication
between client and server should be NONE, INTEGRAL, or
CONFIDENTIAL. NONE means that the application does not require any
transport guarantees. A value of INTEGRAL means that the application
requires that the data sent between the client and server be sent in
such a way that it can't be changed in transit. CONFIDENTIAL means
that the application requires that the data be transmitted in a
fashion that prevents other entities from observing the contents of
the transmission. In most cases, the presence of the INTEGRAL or
CONFIDENTIAL flag will indicate that the use of SSL is required.

For Particular Pages

Change Render Strategy

Change the rendering strategy in your application.

Code Block
 getRequestCycleSettings().setRenderStrategy(Settings.ONE_PASS_RENDER);

...

Create an annotation.

Code Block
 @Retention(RetentionPolicy.RUNTIME)
 public @interface RequiredSSL { }

...

The following goes in your extended Application class.

Code Block
 @Override
 protected IRequestCycleProcessor newRequestCycleProcessor() {
 	                return new DefaultWebRequestCycleProcessor() {
 	                        @Override
 	                        protected IResponseStrategy newResponseStrategy() {
 	                                return new IResponseStrategy() {
 	                                        public void respond(RequestCycle requestCycle) {
 	                                                IRequestTarget requestTarget = requestCycle
 	                                                                .getRequestTarget();
 	                                                if (requestTarget != null) {
 	                                                        Application.get().logResponseTarget(requestTarget);
 	
 	                                                        WebRequest webRequest = (WebRequest) requestCycle
 	                                                                        .getRequest();
 	                                                        WebResponse webResponse = (WebResponse) requestCycle
 	                                                                        .getResponse();
 	
 	                                                        HttpServletRequest httpServletRequest = webRequest
 	                                                                        .getHttpServletRequest();
 	
 	                                                        Class pageClass = null;
 	
 	                                                        if (requestTarget instanceof IPageRequestTarget) {
 	                                                                IPageRequestTarget pageTarget = 
                                                                                     (IPageRequestTarget) requestTarget;
 	                                                                pageClass = pageTarget.getPage().getClass();
 	                                                        } else if (requestTarget instanceof IBookmarkablePageRequestTarget) {
 	                                                                IBookmarkablePageRequestTarget bookmarkableTarget = 
                                                                                     (IBookmarkablePageRequestTarget) requestTarget;
 	                                                                pageClass = bookmarkableTarget.getPageClass();
 	                                                        }
                                                                if (pageClass != null
 	                                                                        && !httpServletRequest.isSecure()
 	                                                                        && pageClass.isAnnotationPresent(RequiredSSL.class)) {
 	                                                                StringBuffer url = new StringBuffer("https://"
 	                                                                                + httpServletRequest.getServerName());
 	
 	                                                                url.append(":" + MyApplication.get().getSslPort());
                                                                        String q = RequestCycle.get().urlFor(
 	                                                                                requestTarget).toString();
 	                                                                url.append(q);
 	                                                                webResponse.redirect(url.toString());
 	                                                        }
                                                                else /* else added */
 	                                                                requestTarget.respond(requestCycle);
 	                                                }
                                                 }
 	                                };
 	                        }
 	                };
 	        }

...

I tried to apply this but I think there was a bug (at least it didn't work for me). A else was missing before the requestTarget.respond(requestCycle); (see else added in the code).
Additionally, a switch back to non-ssl mode should/could be added by adding a if clause, more ore less like this:-ssl mode should/could be added by adding a if clause, more ore less like this:

Code Block

Code Block

                                                                else if (pageClass != null
 	                                                                        && httpServletRequest.isSecure()
 	                                                                        && !pageClass.isAnnotationPresent(RequiredSSL.class)) {
 	                                                                StringBuffer url = new StringBuffer("http://"
 	                                                                                + httpServletRequest.getServerName());
 	
                                                                        String q = RequestCycle.get().urlFor(
 	                                                                                requestTarget).toString();
 	                                                                url.append(q);
 	                                                                webResponse.redirect(url.toString());
 	                                                        }

Edit (Wicket 1.3.x):

I was not able to get the above to work with 1.3. However, with a few tweaks, I was able to get the proper URL generation. I followed the RequiredSSL annotation requirement. Removed the One Pass Through Render Strategy suggestion. I then copied the WebRequestCycleProcessor locally. Modified the

Code Block

encode(final RequestCycle requestCycle, final IRequestTarget requestTarget) 

and added a

Code Block

doPostEncode() 
Code Block
	public final CharSequence encode(final RequestCycle requestCycle,
			final IRequestTarget requestTarget)
	{
		// First check to see whether the target is mounted
		CharSequence url = pathForTarget(requestTarget);

		if (url != null)
		{
			// Do nothing - we've found the URL and it's mounted.
		}
		else if (requestTarget instanceof IBookmarkablePageRequestTarget)
		{
			url = encode(requestCycle, (IBookmarkablePageRequestTarget)requestTarget);
		}
		else if (requestTarget instanceof ISharedResourceRequestTarget)
		{
			url = encode(requestCycle, (ISharedResourceRequestTarget)requestTarget);
		}
		else if (requestTarget instanceof IListenerInterfaceRequestTarget)
		{
			url = encode(requestCycle, (IListenerInterfaceRequestTarget)requestTarget);
		}
		else if (requestTarget instanceof IPageRequestTarget)
		{
			// This calls page.urlFor(IRedirectListener.INTERFACE), which calls
			// the function we're in again. We therefore need to jump out here
			// and return the url immediately, otherwise we end up prefixing it
			// with relative path or absolute prefixes twice.
			return encode(requestCycle, (IPageRequestTarget)requestTarget);
		}
		// fallthough for non-default request targets
		else
		{
			url = doEncode(requestCycle, requestTarget);
		}

		if (url != null)
		{
			// Add the actual URL. This will be relative to the Wicket
			// Servlet/Filter, with no leading '/'.
			PrependingStringBuffer prepender = new PrependingStringBuffer(url.toString());

			// Prepend prefix to the URL to make it relative to the current
			// request.
			prepender.prepend(requestCycle.getRequest().getRelativePathPrefixToWicketHandler());

// CHANGES vvvvv
			// We need to special-case links to the home page if we're at the
			// same level.
			if (prepender.toString().length() == 0)
			{
				prepender.prepend("./");
			}			
			
			String result = prepender.toString();			

			return doPostEncode( requestCycle, requestTarget, requestCycle.getOriginalResponse().encodeURL(result) );

// CHANGES ^^^^^
			
		}

		// Just return null intead of throwing an exception. So that it can be
		// handled better
		return null;
	}

// CHANGES vvvvv	
	protected CharSequence doPostEncode( final RequestCycle requestCycle,
			final IRequestTarget requestTarget, CharSequence result ) {
		
		return result;
	}
	
// CHANGES ^^^^^

Then used the following SecureWebRequestCycleProcessor

Code Block
public class SecureWebRequestCodingStrategy extends WebRequestCodingStrategy {
	private int httpPort = 80;
	private int httpsPort = 443;

	public SecureWebRequestCodingStrategy(int httpPort, int httpsPort ) {
		this.httpPort = httpPort;
		this.httpsPort = httpsPort ;
	}

	@Override
	protected CharSequence doPostEncode(final RequestCycle requestCycle,
			final IRequestTarget requestTarget, final CharSequence result) {
		PrependingStringBuffer buf = new PrependingStringBuffer(
				stripWicketPath(result.toString()));
		if (requestTarget != null) {
			WebRequest webRequest = (WebRequest) requestCycle.getRequest();

			HttpServletRequest httpServletRequest = webRequest
					.getHttpServletRequest();

			Class targetClass = null;

			if (requestTarget instanceof IBookmarkablePageRequestTarget) {
				targetClass = ((IBookmarkablePageRequestTarget) requestTarget)
						.getPageClass();
			} else if (requestTarget instanceof ISharedResourceRequestTarget) {
				targetClass = ((ISharedResourceRequestTarget) requestTarget)
						.getClass();
			} else if (requestTarget instanceof IListenerInterfaceRequestTarget) {
				targetClass = ((IListenerInterfaceRequestTarget) requestTarget)
						.getTarget().getClass();
			} else if (requestTarget instanceof IPageRequestTarget) {
				targetClass = ((IPageRequestTarget) requestTarget).getPage()
						.getClass();
			}

			if (targetClass != null && !httpServletRequest.isSecure()
					&& targetClass.isAnnotationPresent(RequiredSSL.class)) {
				StringBuffer url = new StringBuffer("https://"
						+ httpServletRequest.getServerName());

				if (443 != httpsPort ) {
					url.append(":" + httpsPort );
				}
				url.append(httpServletRequest.getContextPath());

				url
						.append(stripServletPath(httpServletRequest
								.getServletPath()));

				buf.prepend(url.toString());
			} else if (targetClass != null && httpServletRequest.isSecure()
					&& !targetClass.isAnnotationPresent(RequiredSSL.class)) {
				StringBuffer url = new StringBuffer("http://");
				url.append(httpServletRequest.getServerName());
				if (80 != httpPort ) {
					url.append(":" + httpPort );
				}
				url.append(httpServletRequest.getContextPath());
				url
						.append(stripServletPath(httpServletRequest
								.getServletPath()));

				buf.prepend(url.toString());
			} else {
				if (!buf.toString().startsWith("/")) {
					buf.prepend("/");
				}
				buf.prepend(stripServletPath(httpServletRequest
						.getServletPath()));
				buf.prepend(httpServletRequest.getContextPath());
			}
		}

		return buf.toString();
	}

	private String stripServletPath(String fullPath) {
		int idx = fullPath.indexOf("/", 1);

		return (idx == -1) ? fullPath : fullPath.substring(0, idx);
	}

	private String stripWicketPath(String fullPath) {
		String tmp = fullPath;

		int idx = -1;

		if ((idx = tmp.indexOf("?wicket")) != -1) {
			tmp = "/" + tmp.substring(idx);
		} else if ((idx = tmp.lastIndexOf("../")) != -1) {
			tmp = "/" + tmp.substring(idx + 3);
		}
		else if ( !tmp.startsWith( "/") ) {
			tmp = "/" + tmp;
		}

		return tmp;
	}
}

In my application class, I did the following:

Code Block

	protected IRequestCycleProcessor newRequestCycleProcessor() {
		return new WebRequestCycleProcessor() {
			@Override
			protected IRequestCodingStrategy newRequestCodingStrategy() {
				
				String httpPort = MyApplication.this.getPublicPort();
				int httpPortVal = 80;
				
				if ( httpPort != null && !httpPort.equals( "" )) {
					httpPortVal = new Integer( httpPort ).intValue();
				}
				String httpsPort = MyApplication.this.getSslPort();
				
				if ( httpsPort == null || httpsPort.equals( "" )) {
					return super.newRequestCodingStrategy();
				}
				return new SecureWebRequestCodingStrategy( httpsPortVal, new Integer( httpsPort).intValue() );
			}
		};
	}

By using the above solution, anytime I placed a @RequiredSSL on a Form, Link, Button declaration, the proper URL will be generated (https for secured items and http for non-secure items).

...

Code Block
@Override
protected IRequestCycleProcessor newRequestCycleProcessor() {
    return new WebRequestCycleProcessor() {
        public void respond(RequestCycle requestCycle) {
            IRequestTarget requestTarget = requestCycle.getRequestTarget();
            if (requestTarget != null) {
                WebRequest webRequest = (WebRequest) requestCycle .getRequest();
                WebResponse webResponse = (WebResponse) requestCycle .getResponse();
                HttpServletRequest httpServletRequest = webRequest.getHttpServletRequest();

                Class pageClass = null;
                if (requestTarget instanceof IPageRequestTarget) {
                    IPageRequestTarget pageTarget = (IPageRequestTarget) requestTarget;
                    pageClass = pageTarget.getPage().getClass();
                } else if (requestTarget instanceof IBookmarkablePageRequestTarget) {
                    IBookmarkablePageRequestTarget bookmarkableTarget = (IBookmarkablePageRequestTarget) requestTarget;
                    pageClass = bookmarkableTarget.getPageClass();
                }

                if (pageClass != null && !httpServletRequest.isSecure() &&
                        pageClass.isAnnotationPresent(RequiredSSL.class)) {
                    // We should switch to https
                    StringBuffer url = new StringBuffer("https://");
                    url.append(httpServletRequest.getServerName());
                    url.append(":" + MyApplication.get().getHttpsPort());

                    url.append(webRequest.getHttpServletRequest().getContextPath());
                    url.append(webRequest.getServletPath());
                    webResponse.redirect(url.toString());
                } else if (pageClass != null && httpServletRequest.isSecure() &&
                        !pageClass.isAnnotationPresent(RequiredSSL.class)) {
                    // We should switch to http
                    StringBuffer url = new StringBuffer("http://");
                    url.append(httpServletRequest.getServerName());
                    url.append(":" + MyApplication.get().getHttpPort());

                    url.append(webRequest.getHttpServletRequest().getContextPath());
                    url.append(webRequest.getServletPath());
                    webResponse.redirect(url.toString());
                } else {
                    // We should just respond!
                    requestTarget.respond(requestCycle);
                }
            }
        }
    };
}