You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 4 Next »

An explanation of how to transparently switch from http to https.

Table of contents

Change Render Strategy

Change the rendering strategy in your application.

 getRequestCycleSettings().setRenderStrategy(Settings.ONE_PASS_RENDER);

I could not get this to work with the other strategies because you cannot send more than one redirect in the same request. You lose some features like avoiding double submit, but you can avoid that with some javascript. You gain some performance because the rendering is also done in the same request.

Create RequiredSSL Annotation

Create an annotation.

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

Create New Response Strategy

Check if the response page's class has the @RequiredSSL annotation. If it does, redirect to the response page in SSL mode.

The following goes in your extended Application class.

 @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());
 	                                                        }
 	                                                        requestTarget.respond(requestCycle);
 	                                                }
                                                 }
 	                                };
 	                        }
 	                };
 	        }

There are 2 important pieces of configuration that will change based on your environment.

1. SSL Port: There is no way to determine the SSL port being used via the servlet spec API, so this needs to be set manually. Grab the SSL port from your configuration. (Or better yet, set it with Spring in your applicationContext.xml from a properties file)

2. Hostname: In the code below, httpServletRequest.getServerName() is used to determine the hostname. This may not always work, for example in a clustered environment where your website's hostname resolves to an IP address on a router and each application server has a unique hostname like appserver1 and appserver2. If you have this kind of setup, it would be best to grab the hostname from a configuration file or set it with Spring.

Annotate Your Pages

Add @RequiredSSL to any Page that requires SSL!

  • No labels