Thursday, August 3, 2017

Spring Boot: HTTPS and HTTP with Redirection Configuration (SSL/TLS)





To enable an application using Spring Boot to use secure connection, follow the steps described
below.


1. Generate the certificate.

Use Java's keytool utility to generate a self-signed certificate or by one.
For self-signed certificate, do:

  keytool -genkey -alias tomcat -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 -validity 3650


This command generates the file keystore.p12, a PKCS12 keystore containing the certificate in it and using "tomcat" as alias.

Output example:

$ keytool -genkey -alias tomcat -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 -validity 3650
Password?: tomcat Again: tomcat Your first and last names? [Unknown]: john doe Organizational unit? [Unknown]: unitOne Your company's name? [Unknown]: myEnterprise Your city or locality? [Unknown]: Rio de Janeiro Your state? [Unknown]: RJ Your country - two letters? [Unknown]: BR

This command generates a PKCS12 keystore, denoted by keystore.p12.
Move the generated file to project's root dir.
Example:
- windows:
move keystore.p12 $PROJECT_ROOTDIR
- *nix:
mv keystore.p12 $PROJECT_ROOTDIR


2. Set project's configuration file.
If using yaml and MySQL, it could be something like shown below, otherwise, if using ".properties" just convert to its notation using dots ('.').  Example: server.contextPath=/

server:
  contextPath: /
spring:
  profiles: 
    active: dev  #if using profile
---
spring:
  profiles: dev, default
server:
  port: 8443 #default HTTPS
  ssl:
    key-store: keystore.p12
    key-store-password: tomcat
    keyStoreType: PKCS12
    keyAlias: tomcat
datasource:
  setget:
    url: jdbc:mysql://localhost:3306/myproject
    username: adminName
    password: myPass
#    driverClassName: org.gjt.mm.mysql.Driver
    driverClassName: com.mysql.jdbc.Driver
    defaultSchema: mySchema
    maxPoolSize: 20
    hibernate:
#      dialect: org.hibernate.dialect.MySQLDialect
      dialect: org.hibernate.dialect.MySQL5Dialect
      hbm2ddl.method: update
      show_sql: true
      format_sql: true


3. Create a @SpringBootApplication class:

br.com.setget.control.TomcatTwoConnectorsApplication

package br.com.setget.control;

import org.apache.catalina.Context;
import org.apache.catalina.connector.Connector;
import org.apache.tomcat.util.descriptor.web.SecurityCollection;
import org.apache.tomcat.util.descriptor.web.SecurityConstraint;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class TomcatTwoConnectorsApplication {

@Bean
public EmbeddedServletContainerFactory servletContainer() {
TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory() {
@Override
protected void postProcessContext(Context context) {
SecurityConstraint securityConstraint = new SecurityConstraint();
securityConstraint.setUserConstraint("CONFIDENTIAL");
SecurityCollection collection = new SecurityCollection();
collection.addPattern("/*");
securityConstraint.addCollection(collection);
context.addConstraint(securityConstraint);
}
};
tomcat.addAdditionalTomcatConnectors(initiateHttpConnector());
return tomcat;
}

private Connector initiateHttpConnector() {
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
connector.setScheme("http");
connector.setPort(8080);
connector.setSecure(false);
connector.setRedirectPort(8443);
return connector;
}

}

3b. If it is used a not proper configuration class, the application may fail to start.
In such cases, it may return a message file when the http redirection fails, for instance, like this:

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate 
[org.springframework.web.servlet.HandlerMapping]: Factory method 'defaultServletHandlerMapping' threw exception; 
nested exception is java.lang.IllegalArgumentException: A ServletContext is required to configure default servlet handling
Caused by: java.lang.IllegalArgumentException: A ServletContext is required to configure default servlet handling


This procedure was created based on the documentation below wich may be used as complementary searching source.
Thanks to the authors.

https://drissamri.be/blog/java/enable-https-in-spring-boot/

https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples/spring-boot-sample-tomcat-multi-connectors

No comments:

Post a Comment

eclipse: java: SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder" or Exception in thread "main" java.lang.NoClassDefFoundError: org/slf4j/impl/StaticLoggerBinder

  >PROBLEM Using Eclipse, you try to run a simple logging test using "org.slf4j.Logger" like the sample below: package Test; im...