配置问题-在docker Ornged的nginx https反向代理后面通过http basic-authentication服务React应用和Spring Boot后端

时间:2018-10-17 16:55:45

标签: reactjs docker spring-boot nginx https

我有一个无法解决的问题。

当我查询springboot后端时,它工作正常。要求输入密码,然后在我通过身份验证时收到答案。

但是,如果我先调用前端(基本身份验证也可以),但是nginx代理不再将查询转发到spring-boot后端。

能否请我帮我弄清楚我的配置出了什么问题。我忘记了https设置吗?

实际上,如果我关闭ssl,那么它运行良好。而且,使用ssl禁用基本身份验证并不能解决问题。

感谢帮助

以下是更多详细信息:

  • 我有一个使用create-react-app工具创建的react应用。
  • 该应用调用了Spring Boot后端。
  • 我使用docker运行所有这些东西。
  • 我使用https来防止基本身份验证的明文密码。
  • 我以以下示例名称为应用程序服务:https://myPublicHostname(在端口443上)
  • 使用以下名称必须可以访问后端:https://myPublicHostname/rest/myapi/

这是我正在部署的文件结构:

WebDockerService
\-- my-react-app
    \-- public
    \-- src
    \-- package.json
    \-- default.conf
    \-- Dockerfile
    \-- fullchain.pem
    \-- htpasswd
    \-- privkey.pem
\-- my-api
    \-- my-api-0.0.1-SNAPSHOT.jar
    \-- Dockerfile
\-- docker-compose.yml

这是我的Docker组成文件

version: '3.1'
services:
  frontendwithproxy:
   build: ./my-react-app
   ports: 
     - 80:80
     - 443:443 
  springbootbackend:
   build: ./my-api
   ports:
     - 8080:8080
 networks:
  default:
    external:
      name: netDev

这是用于构建nginx服务器的“ my-react-app” Dockerfile

### STAGE 1: Build ###
FROM node:9.11.1 as build
RUN mkdir /usr/src/app
WORKDIR /usr/src/app
ENV PATH /usr/src/app/node_modules/.bin:$PATH
COPY package.json /usr/src/app/package.json
RUN npm install --silent
RUN npm install react-scripts -g --silent
COPY . /usr/src/app
RUN npm run build

### STAGE 2: Production Environment ###
FROM nginx:1.13.12-alpine

COPY fullchain.pem /etc/nginx/fullchain.pem
COPY privkey.pem /etc/nginx/privkey.pem
COPY default.conf /etc/nginx/conf.d/default.conf
COPY htpasswd /etc/nginx/conf.d/htpasswd
COPY --from=build /usr/src/app/build /usr/share/nginx/html

EXPOSE 80 443

CMD ["nginx", "-g", "daemon off;"]

这是nginx的default.conf文件

server {
    #To redirect http traffic to ssl
    listen 80;
    return 301 https://myPublicHostname$request_uri;
}

server{

    listen          443 ssl;
    server_name     myPublicHostname;
    #root containing react app files
    root            /usr/share/nginx/html;

    #Basic authentication enabling
    auth_basic              "Restricted Access!";
    auth_basic_user_file    /etc/nginx/conf.d/htpasswd;

    #SSL Settings
    ssl_certificate /etc/nginx/fullchain.pem;
    ssl_certificate_key /etc/nginx/privkey.pem;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;
    ssl_ecdh_curve secp384r1;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers "ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA";
    ssl_prefer_server_ciphers on;
    add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;";
    add_header X-Content-Type-Options nosniff;
    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Robots-Tag none;
    ssl_stapling on;
    ssl_stapling_verify on;

    #Location for springboot api
    location /rest {
        proxy_set_header        Host $host;
        proxy_set_header        X-Real-IP $remote_addr;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_http_version      1.1;
        proxy_set_header        Upgrade $http_upgrade;
        proxy_set_header        Connection "upgrade";
        proxy_set_header        X-Forward-Proto http;
        proxy_set_header        X-Nginx-Proxy true;

        proxy_redirect          off;
        proxy_pass              http://192.168.1.125:8080;          
    }
}

这是springboot后端的Dockerfile

FROM openjdk:8-jdk-alpine
COPY my-api-0.0.1-SNAPSHOT.jar /opt/my-api/my-api.jar
ENTRYPOINT ["/usr/bin/java"]
CMD ["-jar", "/opt/my-api/my-api.jar", "/opt/my-api/public","/opt/my-api/temp", "/opt/my-api/uploads"]
VOLUME ["/opt/my-api/public","/opt/my-api/temp","/opt/my-api/uploads"]
EXPOSE 8080

编辑:

nginx是唯一的入口点。输入的所有内容都必须实现基本身份验证。我不会在http上激活它,因为我不想允许这种潜在的泄漏。但是基本身份验证不是问题,因为当我停用它时,总是会出现问题。

更令人惊讶的是,获取图片的后端“ GET”查询工作正常。图片显示良好。它们可用于标记和浏览器url字段。

但是其他返回zip或其他内容类型的GET查询不起作用。 (在标记中的效果不如在浏览器中键入的效果好。)

编辑2:

实际上,它似乎有效。因为当我使用一个休息客户端并在后端查询我的资源时,结果是很不错的。另外,如果我在代码winthin react app中调用后端,结果就会到达。

但是当我用这样的href调用后端时:

<a 
  href={"https://myPublicHostname/rest/my-api/getZipFile?value=1,2,3,4,5"}
  target="_blank"
>

然后后端不接收get查询。

所以myabe缺少一些标头!?

2 个答案:

答案 0 :(得分:0)

When I query my springboot backend it works fine. The password is asked then when I’m authenticated, I receive the answer.

如果同时在nginx和backend上都启用了身份验证,那么您将需要某种方式,以便nginx可以对后端进行身份验证。

当nginx尝试访问后端时,后端将超时以进行身份​​验证。验证信息可能已加密,无法取出。

首先仅在nginx(使用SSL)上通过身份验证对它进行测试,然后在后端打开auth。

您还可以尝试关闭从nginx到后端的SSL。

如果不是上述情况,并且后端没有身份验证和SSL,则以下是有关nginx SSL基本身份验证问题的答案:

Nginx basic auth working on http but not on https

,因此您首先需要确保将nginx配置为在http和https上都要求输入密码,然后再进行其余工作。您可以先在一些简单的页面上对其进行测试。

答案 1 :(得分:0)

这样解决问题:

<a 
  href="/rest/photo/getZipFile?value=1,2,3" 
  target="_blank"
  rel="noopener noreferrer"
  download="AnyCustomFileName.zip"
>
    ...button
</a>

这个简单的属性可以改变一切:

download =“ AnyCustomFileName.zip”

使用它,浏览器添加不同的标题,然后Nginx实现将其路由到正确的目的地。

适用于Edge,Chrome,Samsung Internet和Firefox ...,但是Fireforx仅在私人会话中工作。