【问题标题】:How do I force SSL on my Spring Boot app that uses OAuth2 on AWS ElasticBeanstalk and Nginx?如何在 AWS ElasticBeanstalk 和 Nginx 上使用 OAuth2 的 Spring Boot 应用程序上强制 SSL?
【发布时间】:2019-04-16 18:45:17
【问题描述】:

我正在尝试使用参考文档强制 SSL

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

但是,我已经有了

@Configuration
class WebSecurityConfiguration  {

当我添加extends WebSecurityConfigurerAdapter,甚至没有添加protected void configure(HttpSecurity http) 时,对非Oauth2 页面/home/ 的请求会无缘无故地重定向到/login。它适用于属性设置。只需扩展类 extends WebSecurityConfigurerAdapter 就可以破坏应用程序。 OAuth2 保护了其他不相关的路由。我之前在设置 Oauth2 时看到过这种不确定的随机行为。

这是WebSecurityConfiguration 类的概要。

@Configuration
class WebSecurityConfiguration {

    @Autowired
    UserMapper userMapper;

    @Bean
    PasswordEncoder passwordEncoder() {

    @Bean
    protected UserDetailsService userDetailsService() {

就是这样。

我尝试添加一个 Nginx 配置以重定向到 SSL,在这个答案 https://stackoverflow.com/a/53310987/148844 中,但它不起作用。它确实重定向到 SSL,但我得到所有路径的 404 错误

HTTP 状态 404 - /home
输入状态报告
留言 /home
描述 请求的资源不可用。
Apache Tomcat/8.0.47

所以它是强制 SSL 并访问 Tomcat,但 Spring Boot 应用程序完全搞砸了。就好像 ZIP 中的 WAR 文件从未部署过一样。

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

【问题讨论】:

  • 你的WebSecurityConfiguration 班级到底在做什么?
  • @DarrenForsythe 添加了课程大纲。

标签: spring amazon-web-services spring-boot amazon-elastic-beanstalk


【解决方案1】:

为此我放弃了使用 Spring Boot,因为它太不稳定并求助于 Nginx 配置选项。这行得通,尽管仅仅制作 ZIP 似乎过于冗长。 Elastic Beanstalk 中存在一个错误的附加问题!

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

部署 ZIP 时,不会部署 WAR!所以我必须创建一个解决方法来在 ZIP 中创建 两个 WAR 文件。 (只有一个,即使叫ROOT.war,也行不通。)

我找不到使用 Maven 创建空文件的方法,因此我在项目根目录中创建了一个空的 empty.war 文件并将其捆绑在 ZIP 中,以诱使 Elastic Beanstalk 正常工作和部署应用程序。真是一团糟!哎哟!

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>

而配置文件就在项目根目录下。我不知道该放在哪里——它不是源代码。

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

【讨论】:

    【解决方案2】:

    我认为您不必关心在tomcatapplication 端启用SSL,这不是必需的,只需启用sslnginx

    您应该简单地终止 nginx 上的 SSL 并将 proxy/reverse-proxy 传递给 tomcat

    这里有一些参考资料来证明我的上述观点。 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

    在您的情况下,您需要按照以下步骤操作。

    1)创建00_application.conf文件并将其放在.ebextensions/nginx/conf.d/elasticbeanstalk/下。

    2)00_application.conf文件应该有以下内容。

    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) 停止列出到默认端口 80 并重定向到 443,这意味着如果您将 http://foo.bar/ 作为您的域,则将其重定向到 https://foo.bar/,打开位于 .ebextensions/nginx/nginx.confnginx.conf 文件。另外,请务必写下以下行,include conf.d/elasticbeanstalk/*.conf;

    server {
    listen 80;
    
    server_name foo.bar;
    return 301 https://foo.bar$request_uri;
    }
    

    我认为 O-Auth、任何 Auth、Spring boot v/s non springs boot 应用程序在这里都不那么重要。

    请务必遵循AWS documentation 中的说明,以及扩展默认 nginx 配置部分。 具体阅读有关的说明 我希望这能回答你的问题。我还没有在 beanstalk 上测试过上面的所有内容,但其余的都在 EC2、tomcat 和 nginx 代理上进行了测试。试试这个并在评论部分发布您可能遇到的特定问题。

    【讨论】:

    • 我不认为 1) 和 2) 是正确的。 docs.aws.amazon.com/elasticbeanstalk/latest/dg/… 说“conf.d 文件夹中带有 .conf 扩展名的文件包含在默认配置的 http 块中。conf.d/elasticbeanstalk 文件夹中的文件包含在 http 块中的服务器块中。”由于00_application.conf 已经包含在服务器块中,我认为您不再需要服务器。所以文件应该在其他地方或者不应该有 server 块。
    • 当负载均衡器和 Tomcat 服务器位于不同的 IP 地址时,如何硬编码 EC2 实例的 IP?它如何自动扩展应用程序以增加 EC2 实例?
    • 这也无法解释为什么当我使用 Nginx 重定向到 SSL 时,Tomcat 会为应用程序提供 404 错误。
    • 好的,很抱歉,但我认为,您正在混合不同的问题,并使其变得复杂。一一解决问题。 1)http到https。正如我所解释的,这很简单。 2) o-auth 问题。 3)负载均衡。 Nginx 也进行负载平衡,但据我所知,在弹性 beantalk 的情况下不需要它,因为如果配置它会自动扩展。我建议您尝试我的步骤,如果有任何失败,我们也应该能够解决。编码愉快,谢谢
    猜你喜欢
    • 2016-12-24
    • 1970-01-01
    • 1970-01-01
    • 2015-12-24
    • 2013-12-20
    • 1970-01-01
    • 2017-09-28
    • 1970-01-01
    • 2017-09-23
    相关资源
    最近更新 更多