35

I have create sample jHipster app. Now I want to add self signed SSL certificate and test in local to have a access to https. How to achieve this?

Raj
  • 739
  • 1
  • 10
  • 23

3 Answers3

78

These instructions are applicable for all Spring Boot applications, on which JHipster is based. I have tested this on a newly generated JHipster 2.7 project.

You need to complete these steps when starting from scratch:

  1. Generate a self-signed certificate
  2. Add the SSL properties to your application.properties or application.yml as mentioned in the Spring Boot documentation
  3. (Optional) Redirect HTTP to HTTPS

Generating a self-signed certificate

First you need to generate your self-signed certificate in your project directory, this can be done with keytool, which is utility script provided by Java:

keytool -genkey -alias tomcat -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 -validity 3650
Enter keystore password:  
Re-enter new password:
What is your first and last name?
  [Unknown]:  
What is the name of your organizational unit?
  [Unknown]:  
What is the name of your organization?
  [Unknown]:  
What is the name of your City or Locality?
  [Unknown]:  
What is the name of your State or Province?
  [Unknown]:  
What is the two-letter country code for this unit?
  [Unknown]:  
Is CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown correct?
  [no]:  yes

I have chosen password mypassword so this is the one I will use in the next step. When you have done this, you will see a keystore.p12 in your current directory.

Add the SSL properties to your application.properties or application.yml as mentioned in the Spring Boot documentation

Now you need to add the HTTPS connector properties for Tomcat. You can find the property (yml) files in src/main/resources/ and you need to update the application.yml (or if it is only for development in application-dev.yml with the following properties:

server:
  ssl:
    key-store: keystore.p12
    key-store-password: mypassword
    keyStoreType: PKCS12
    keyAlias: tomcat

Now you can package your application with Maven (or Gradle if you chose that for your JHipster application) using mvn clean package and run the application using mvn spring-boot:run. You can now access your application on https://localhost:8080

For simplicity I did not change the port, but ideally you should change it as well in the properties files, but I left it out since they are already defined in application-dev.yml and application-prod.yml so you would have to change it in there or remove it and put it in the general application.yml


(Optional) Add redirect HTTP to HTTPS

You can only enable one protocol through the application.properties, so when you do this like above only HTTPS will work. If you want HTTP to work too, and redirect to HTTPS you have to add a @Configuration class like below

@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;
  }

This response is basically a copy of my blog post on the same subject: http://www.drissamri.be/blog/java/enable-https-in-spring-boot/

Andrii Abramov
  • 10,019
  • 9
  • 74
  • 96
Driss Amri
  • 1,805
  • 2
  • 20
  • 28
  • do i need to keep keystore.p12 file in project's classpath? – Raj Apr 14 '15 at 11:22
  • 1
    I left the keystore.p12 in the root of my project and ran from the root with mvn spring-boot:run. If you put it on your classpath you can change the key-store property to: key-store: classpath:keystore.p12 – Driss Amri Apr 14 '15 at 11:29
  • Hi @Driss. now i'm not able to access sample app .. if I type http://127.0.0.1:8080/# in the browser, i.e., if I type http:// it should redirect me to https:// – Raj Apr 22 '15 at 10:15
  • 1
    You can only activate one protocol through the application properties at this time. If you want HTTP and HTTPS you will need to active one programmatically. I blogged about this use case on http://www.drissamri.be/blog/java/enable-https-in-spring-boot/ and I'll edit the response here too – Driss Amri Apr 22 '15 at 12:19
  • thank you .. It means I can create ContainerConfiguration.java in config package of jHipster sample app and paste code snippet mentioned in blog? – Raj Apr 22 '15 at 13:30
  • Yes, just make sure you annotate it with @Configuration – Driss Amri Apr 22 '15 at 13:32
  • thanks I am able to run my app with https from eclipse, but if I run if from jar package it throws me a port error, do I need to configure anything else? – jesicadev18 Jun 07 '17 at 18:15
  • @DrissAmn Your sample shows keyStoreType and keyAlias as two of the property names. Is it supposed to be key-store-type and key-alias? That's what IntelliJ's intellisense shows and it's odd to see "dash" based property names mixed with "camel" cased property names. – Robert Oschler Aug 09 '17 at 16:41
  • Spring Boot uses relaxed binding so both ways work. But it would make more sense to pick one way and stick consistently with it in a real project. – Driss Amri Aug 10 '17 at 09:36
  • Can someone please add imports for redirect HTTP to HTTPS code ? – user3364181 Aug 06 '18 at 11:00
  • I did every step beside last one since you didnt put imports and it doesn't work : http://prntscr.com/kfb2ni – user3364181 Aug 06 '18 at 13:21
  • I konow this may be too late, but i have followed all steps and I get: Your connection is not private. Btw I am running the server in dev profile. – boandriy Aug 28 '18 at 15:38
5

To extend the Driss Amri brilliant answer on how to re-enable BrowserSync.

If you choose not to support http, or if http is redirected to https, BrowserSync will not work. To make it work again, few changes are necessary in:

  1. gulp/config.js, apiPort and uri to:

    apiPort: 8443, 
    uri: 'https://localhost:',
    
  2. gulp/serve.js: add options.rejectUnauthorized = false; into proxyRoutes so that node does not complain about self signed certificate:

    proxyRoutes.map(function (r) {
        var options = url.parse(baseUri + r);
        options.route = r;
        options.preserveHost = true;
        options.rejectUnauthorized = false;
        return proxy(options);
    }));
    
  3. optionally let BrowserSync serve content over https too. I recommend it with Spring Social to save some trouble. Just add https: true into browserSync call in gulp/serve.js:

    browserSync({
        open: true,
        port: config.port,
        server: {
            baseDir: config.app,
            middleware: proxies
        },
        https: true
    });
    

    Now BrowserSync will serve content with self signed certificate shipped with it. It is possible to reuse the one created for Spring Boot, more on BrowserSync homepage.

Community
  • 1
  • 1
Michal Foksa
  • 11,225
  • 9
  • 50
  • 68
2

For those using webpack instead of gulp you can complete Driss Amri's answer with two changes:

modify the proxy.conf.json:

{
    "*": {
        "target": "https://localhost:8443",
        "secure": true
    }
}

this will redirect API requests to the new https address. Then alter also webpack file for instance here a webpack.dev.js modified example:

module.exports = webpackMerge(commonConfig({ env: ENV }), {
devtool: 'eval-source-map',
devServer: {
    contentBase: './target/www',
    proxy: [{
        context: [
            /* jhipster-needle-add-entity-to-webpack - JHipster will add entity api paths here */
            '/api',
            '/management', ...
            '/auth'
        ],
        target: 'https://127.0.0.1:8443',
        /* set secure to false here, otherwise self-signed certification cause DEPTH_ZERO_SELF_SIGNED_CERT proxy errors */
        secure: false
    }]
},
A. Masson
  • 2,287
  • 3
  • 30
  • 36
  • 1
    What about prod ? webpackprod.prod.js ? Since Driss Amri's answer is not working for me what can i change there ? – user3364181 Aug 06 '18 at 13:35
  • Webpack make uses of environment variables as explained here: https://atendesigngroup.com/blog/managing-dev-and-production-builds-webpack so for instance the name would be webpack.prod.js within this case – A. Masson Aug 07 '18 at 14:31