Skip to content

Latest commit

 

History

History
149 lines (106 loc) · 5.3 KB

README.md

File metadata and controls

149 lines (106 loc) · 5.3 KB

TicTacToe

A sample web app to play Tic Tac Toe against the computer. The application requires minimum JDK 21 to run locally.

Technologies

This application has several components:

  • Running on JDK 21+ and built with Maven.
  • Setup built with Spring Boot (v3.2.2), persistency layer with JPA and H2 database, UI with Thymeleaf with Bootstrap
  • Containerized with Dockerfile and deployed with Docker Compose.
UI Component Link
Header https://getbootstrap.com/docs/5.3/examples/headers/
Footer https://getbootstrap.com/docs/5.3/examples/footers/
Sign In and Register https://getbootstrap.com/docs/5.3/examples/sign-in/

How to create the keystore and truststore

In order to build an example keystore, you can use the following series of commands:

  1. Create a CA certificate, by running openssl req -x509 -sha256 -days 3650 -newkey rsa:4096 -keyout localCA.key -out localCA.crt
  2. Create a certificate signing request, by running openssl req -new -newkey rsa:4096 -keyout localhost.key -out localhost.csr
  3. Make an extension file (local.ext) containing additional hosts and IPs that your certificate should authorize:
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
subjectAltName = @alt_names
[alt_names]
DNS.1 = localhost
DNS.2 = springboot
IP.1 = 127.0.0.1
  1. Sign the request with our localCA.crt certificate and its private key:
openssl x509 -req -CA localCA.crt -CAkey localCA.key -in localhost.csr \
    -out localhost.crt -days 365 -CAcreateserial -extfile local.ext
  1. Create the keystore by importing the certificate created at previous step:
openssl pkcs12 -export -out keystore.p12 -name "localhost" -inkey localhost.key -in localhost.crt

To enable mutual authentication, you need to generate a truststore and generate client certificates:

  1. Create a truststore by running:
keytool -import -trustcacerts -noprompt -alias ca -ext san=dns:localhost,ip:127.0.0.1 -file localCA.crt -keystore truststore.p12
  1. Generate a client-side certificate signing request with common name (CN) Ana:
openssl req -new -newkey rsa:4096 -nodes -keyout ana.key -out ana.csr -subj '/CN=ana'
  1. Sign the request with the existing CA:
openssl x509 -req -CA localCA.crt -CAkey localCA.key -in ana.csr -out ana.crt -days 365 -CAcreateserial
  1. Package the signed certificate and the private key into the PKCS file:
openssl pkcs12 -export -out ana.p12 -name "ana" -inkey ana.key -in ana.crt
  1. Import the generated certificate (ana.p12) in your browser.

Do not forget to reference the location of your keystore/truststore in the application.properties file:

server.ssl.bundle=mybundle
spring.ssl.bundle.jks.mybundle.keystore.location=stores/keystore.p12
spring.ssl.bundle.jks.mybundle.truststore.location=stores/truststore.p12

IMPORTANT For demo purposes, application.properties contains the passwords in clear. For production environments you must consider encrypting your passwords.

How to play

You can start the application locally from your IDE or by running the following command in a terminal window:

./mvnw spring-boot:run

When accessing the application on https://localhost:8443, you will be asked to sign in to play. If you didn't register, you can do so by clicking the register link. If there is an user already registered with a chosen username, please select a different one.

Once you register, login with your chosen username and password to play. Have fun!

How to deploy

You can deploy the application locally via Docker Compose. First build the application using:

./mvnw clean verify

By default, the provided docker compose file has enabled remote JMX connection via JDK_JAVA_OPTIONS environment variable:

        -Dcom.sun.management.jmxremote.ssl=false
        -Dcom.sun.management.jmxremote.authenticate=true
        -Dcom.sun.management.jmxremote.rmi.port=1099
        -Dcom.sun.management.jmxremote.port=1099
        -Dcom.sun.management.jmxremote=true
        -Dcom.sun.management.jmxremote.access.file=/etc/jmxremote/jmxremote.access
        -Dcom.sun.management.jmxremote.password.file=/etc/jmxremote/jmxremote.password

and mounts the jmxremote.access and jmxremote.password files as volumes from stores folder:

    volumes:
      - ./stores/jmxremote.access:/etc/jmxremote/jmxremote.access
      - ./stores/jmxremote.password:/etc/jmxremote/jmxremote.password

If you wish to keep that configuration, make sure that you can read and write the /etc/jmxremote/jmxremote.password and other users have no access to it. An example on how to do that on Mac/Linux is by running the following command over :

chmod 0600 stores/jmxremote.password 

Now you can invoke docker-compose up command:

docker-compose up --build

This will build a local containerize environment for you to inspect the application.

If you wish to deploy in other environments, you can always build and push a docker image using:

docker buildx build --platform=linux/amd64  --tag <registry>/<username>/tictactoe:1.0 . --no-cache