7

I'm trying to force SSL using the reference documentation

https://docs.spring.io/spring-boot/docs/current/reference/html/howto-security.html#howto-enable-https

However, I already have

@Configuration
class WebSecurityConfiguration  {

When I add extends WebSecurityConfigurerAdapter, and not even protected void configure(HttpSecurity http), then requests to a non-Oauth2 page /home/ are redirected to /login for no reason. It works with the property settings. Just by extending the class extends WebSecurityConfigurerAdapter breaks the app. There are other unrelated routes secured by OAuth2. I've seen this non-deterministic random behavior before while setting up Oauth2.

This is the outline of the WebSecurityConfiguration class.

@Configuration
class WebSecurityConfiguration {

    @Autowired
    UserMapper userMapper;

    @Bean
    PasswordEncoder passwordEncoder() {

    @Bean
    protected UserDetailsService userDetailsService() {

And that's it.

I tried to add a Nginx configuration to redirect to SSL, in this answer https://stackoverflow.com/a/53310987/148844, but it didn't work. It does redirect to SSL but I get 404 errors for all paths

HTTP Status 404 - /home
type Status report
message /home
description The requested resource is not available.
Apache Tomcat/8.0.47

tomcat 404

So it is forcing SSL and accessing Tomcat, but the Spring Boot app is completely messed up. It's as if the WAR file in the ZIP was never deployed.

Reference: https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/java-tomcat-proxy.html#java-tomcat-proxy-nginx

Chloe
  • 25,162
  • 40
  • 190
  • 357

2 Answers2

2

I gave up using Spring Boot for this as it's so flaky and resorted to an Nginx configuration option. This worked, though it seems excessively verbose for just making a ZIP. There was the additional problem of a bug in Elastic Beanstalk!

AWS Elastic Beanstalk Tomcat works with .war but not .zip

When deploying the ZIP, it would not deploy the WAR! So I had to create a workaround to create two WAR files in the ZIP. (Just one, even called ROOT.war, would not work.)

I could not find a way to create an empty file with Maven, so I created an empty empty.war file in the project root directory and bundled it inside the ZIP to trick Elastic Beanstalk into working and deploying the app properly. What a mess! Oy vey!

pom.xml
        <plugin> <!-- To add .ebextensions/ Nginx config for ElasticBeanstalk -->
          <artifactId>maven-assembly-plugin</artifactId>
          <configuration>
            <descriptors>
              <descriptor>assembly.xml</descriptor>
            </descriptors>
          </configuration>
          <executions>
            <execution>
              <id>make-assembly</id>
              <phase>package</phase>
              <goals>
                <goal>single</goal>
              </goals>
            </execution>
          </executions>
        </plugin>           
assembly.xml
<assembly 
  xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
  <id>bin</id>
  <baseDirectory>/</baseDirectory>
  <formats>
    <format>zip</format>
  </formats>
  <files>
    <file>
      <source>empty.war</source>
      <outputDirectory/>
    </file>
    <file>
      <source>${project.build.directory}/AppName-0.0.3-SNAPSHOT.war</source>
      <outputDirectory/>
      <destName>ROOT.war</destName>
    </file>
  </files>

  <fileSets>
    <fileSet>
      <directory>${project.basedir}</directory>
      <outputDirectory>/.ebextensions/nginx/conf.d/elasticbeanstalk/</outputDirectory>
      <includes>
        <include>force-https.conf</include>
      </includes>
    </fileSet>
  </fileSets>
</assembly>

And the configuration file is just in the project root. I didn't know where else to put it - it's not source code.

force-ssl.conf
if ($http_x_forwarded_proto = 'http') {
    return 301 https://$host$request_uri;
}

http://maven.apache.org/plugins/maven-assembly-plugin/assembly.html

Community
  • 1
  • 1
Chloe
  • 25,162
  • 40
  • 190
  • 357
0

I think you need not to care about enabling the SSL on tomcat or application side and its not required, just enable ssl up to nginx.

You should be simple terminating the SSL on nginx and passing the proxy/reverse-proxy to tomcat.

Here are some of references to prove my above point. https://docs.nginx.com/nginx/admin-guide/security-controls/terminating-ssl-http/ https://www.digitalocean.com/community/tutorials/how-to-set-up-nginx-load-balancing-with-ssl-termination

In your case, you need to follow below steps.

1)Create 00_application.conf file and place it under the, .ebextensions/nginx/conf.d/elasticbeanstalk/.

2)00_application.conf file should have following content.

server {
    listen          443 ssl;
    server_name     www.example.com;
    ssl_certificate www.example.com.crt;
    #...
    location /{
//your tomcat port, I'm here assuming the your beanstalkserver tomcat is listing to 8080.
proxy_pass http://127.0.0.1:8080;
}
}

3)Stop listing to default port 80 and redirecting to 443, meaning if you have http://foo.bar/ as your domain, you redirect it https://foo.bar/, Open the nginx.conf file located at .ebextensions/nginx/nginx.conf. Also, make sure to write following line, include conf.d/elasticbeanstalk/*.conf;

server {
listen 80;

server_name foo.bar;
return 301 https://foo.bar$request_uri;
}

I think O-Auth, none of Auth, Spring boot v/s non springs boot apps are less important here.

Please make sure to follow note written in AWS documentation, and section Extending the Default nginx Configuration. Specifically read the note that talks about I hope that answers your question. I have not tested everything of above on beanstalk, but rest are tested on EC2, tomcat with nginx proxy. Try this and post specific issue that you might be having in comment section.

Red Boy
  • 5,429
  • 3
  • 28
  • 41
  • I don't think 1) and 2) are correct. https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/java-tomcat-proxy.html#java-tomcat-proxy-nginx says "Files with the .conf extension in the conf.d folder are included in the http block of the default configuration. Files in the conf.d/elasticbeanstalk folder are included in the server block within the http block." Since `00_application.conf` is already included in the server block, I don't think you need server in there again. So either the file should be elsewhere or should not have `server` block. – Chloe Nov 24 '18 at 18:49
  • And how would it work to hard-code the IP of the EC2 instance, when the load balancer and Tomcat server are on different IP address? How would it automatically scale the application for additional EC2 instances? – Chloe Nov 24 '18 at 18:50
  • This also doesn't explain why when I redirected to SSL with Nginx, Tomcat was giving 404 errors for the app. – Chloe Nov 24 '18 at 18:54
  • Ok, I'm sorry, but I think, your are mixing different issues, and making it complex. Solve problems one by one. 1) http to https. Which is simple thing, as I have explained. 2) o-auth issue. 3) load balancing. Nginx does load balancing as well, but as far I know, it is not needed in case of elastic beanstalk as it auto scales if configured. I suggest you to try my steps one one if any fails, we should be able to solve that as well. Happy coding, Thanks – Red Boy Nov 24 '18 at 20:29