Fork me on GitHub

Secure Page Tutorial

This tutorial looks at configuring a page to only be accessed via a secure channel (HTTPS).

The below example for this tutorial will implement a simple page to capture card details. The simple page for this tutorial is as follows:

SecurePageHttpServer screen shot.

Tutorial Source

Secure Page

To configure the page to always be accessed via a secure channel, the following is the configuration for the page:

Secure Page configuration screen shot.

Checking the secure check box is the only configuration necessary to ensure use of a secure channel (HTTPS) for accessing the page.

To ease development, WoOF by default runs with a generic security key that is self signed. Typically for development and testing this will require trusting the key within the browser to access the page. This default setup should only be used for development/testing to avoid manual key setup.

For production, a trusted third-party signed security key is recommended to be configured.

Please also see the HttpServerLocation for details on configuring the web application's location for generation of the link URLs.

Template

The page template content is as follows:

<html>
	<body>
		<h1>Enter card details</h1>
		<form action="#{save}" method="POST">
			Card number: <input type="text" name="number" value="${number}" size="19" /> <br />
			Expiry date: <input type="text" name="month" value="${month}" size="2" /> / 
							<input type="text" name="year" value="${year}" size="4" />
			CSC: <input type="text" name="csc" value="${csc}" size="3" /> <br />
			<input type="submit" value="save" />
		</form>
		<a href="#{main}">Back to main page</a>
	</body>
</html>

This is similar HTML to previous tutorials.

Logic Class

The logic for the page is the following:

public class CardLogic {

	@Data
	@HttpParameters
	public static class CardDetails implements Serializable {
		private static final long serialVersionUID = 1L;

		private String number;

		private String month;

		private String year;

		private String csc;
	}

	public CardDetails getTemplateData(CardDetails cardDetails, ServerHttpConnection connection) {

		// Confirm a secure connection (not needed but included for tutorial)
		if (!connection.isSecure()) {
			throw new IllegalStateException();
		}

		// Return the card details for rendering
		return cardDetails;
	}

	public void save(CardDetails cardDetails, ServerHttpConnection connection) {

		// Confirm a secure connection (not needed but included for tutorial)
		if (!connection.isSecure()) {
			throw new IllegalStateException();
		}

		// Logic for processing the card details
	}

}

Again this is similar to previous tutorials.

Remaining Code

The main page is included for completeness of the tutorial code.

<html>
	<body>
		<h1>Main Page</h1>
		<a href="#{card}">Enter card details</a>
	</body>
</html>

Unit Test

The unit test requests the page:

  • directly
  • via a link from another page

The exception within the page logic ensures rendering the response only occurs over a secure channel (HTTPS).

@ExtendWith(OfficeFloorExtension.class)
public class SecurePageTest {

	@RegisterExtension
	public final HttpClientExtension client = new HttpClientExtension(true);

	@Test
	public void testSecurePage() throws Exception {

		// Ensure redirect to secure access to page
		this.assertHttpRequest("http://localhost:7878/card");

		// Ensure redirect to secure link access to page
		this.assertHttpRequest("http://localhost:7878/main+card");
	}

	private void assertHttpRequest(String url) throws IOException {
		HttpResponse response = this.client.execute(new HttpGet(url));
		assertEquals(200, response.getStatusLine().getStatusCode(), "Should be successful (after possible redirect)");
		String entity = EntityUtils.toString(response.getEntity());
		assertTrue(entity.contains("<h1>Enter card details</h1>"),
				"Should be rendering page as secure (and not exception)");
	}

}

Next

The next tutorial looks at securing a specific link.