AmruthPillai / Reactive-Resume

A one-of-a-kind resume builder that keeps your privacy in mind. Completely secure, customizable, portable, open-source and free forever. Try it out today!
https://rxresu.me
MIT License
23.57k stars 2.51k forks source link

RXResume Client and Server Not Communicating with Authentication Provider in Front [BUG] #1290

Open MetaBliss opened 1 year ago

MetaBliss commented 1 year ago

Describe the bug

I currently have RX Resume v3 stack (with client, server and database) installed and running just fine behind Nginx Proxy Manager (NPM).

However, I use Authentik as a separate authentication provider (similar to Keycloak and Authelia but in my opinion has more features) to protect my services. Authentik has a feature called "forward proxy" where via NPM, any user wishing to use the RX Resume service will need to authenticate with Authentik first before being allowed to continue to the login page for RX Resume service. When I have Authentik act as a forward proxy in front of RX Resume, then I cannot login to the RX resume service.

Authentik provided nginx code snippet to put into NPM which allows NPM to redirect client requests back to Authentik first for authentication. Below is the code snippet Authentik generated with my domain name redacted in one spot near the bottom. When I put the code below for RX Resume Client (but not RX Resume Server) then I am able to use the RX Resume service properly - however only RX Resume Client gets protected by Authentik. Because the code below is not pasted for RX Resume Server I cannot protect the Server with Authentik. When I try to put the code below for both RX Resume Client AND Server then I cannot login to my RX Resume instance. Perhaps there is some code to modify below so that RX Resume Server works? I've provided snapshots with my network console in the browser so you can see whats happening.

Authentik Code SNippet to put into NPM to protect services with Authentik in front

# Increase buffer size for large headers
# This is needed only if you get 'upstream sent too big header while reading response
# header from upstream' error when trying to access an application protected by goauthentik
proxy_buffers 8 16k;
proxy_buffer_size 32k;

location / {
    # Put your proxy_pass to your application here
    proxy_pass          $forward_scheme://$server:$port;

    # authentik-specific config
    auth_request        /outpost.goauthentik.io/auth/nginx;
    error_page          401 = @goauthentik_proxy_signin;
    auth_request_set $auth_cookie $upstream_http_set_cookie;
    add_header Set-Cookie $auth_cookie;

    # translate headers from the outposts back to the actual upstream
    auth_request_set $authentik_username $upstream_http_x_authentik_username;
    auth_request_set $authentik_groups $upstream_http_x_authentik_groups;
    auth_request_set $authentik_email $upstream_http_x_authentik_email;
    auth_request_set $authentik_name $upstream_http_x_authentik_name;
    auth_request_set $authentik_uid $upstream_http_x_authentik_uid;

    proxy_set_header X-authentik-username $authentik_username;
    proxy_set_header X-authentik-groups $authentik_groups;
    proxy_set_header X-authentik-email $authentik_email;
    proxy_set_header X-authentik-name $authentik_name;
    proxy_set_header X-authentik-uid $authentik_uid;
}

# all requests to /outpost.goauthentik.io must be accessible without authentication
location /outpost.goauthentik.io {
    proxy_pass          http://NAS-IP:PORT/outpost.goauthentik.io;
    # ensure the host of this vserver matches your external URL you've configured
    # in authentik
    proxy_set_header    Host $host;
    proxy_set_header    X-Original-URL $scheme://$http_host$request_uri;
    add_header          Set-Cookie $auth_cookie;
    auth_request_set    $auth_cookie $upstream_http_set_cookie;

    # required for POST requests to work
    proxy_pass_request_body off;
    proxy_set_header Content-Length "";
}

# Special location for when the /auth endpoint returns a 401,
# redirect to the /start URL which initiates SSO
location @goauthentik_proxy_signin {
    internal;
    add_header Set-Cookie $auth_cookie;
    return 302 /outpost.goauthentik.io/start?rd=$request_uri;
    # For domain level, use the below error_page to redirect to your authentik server with the full redirect path
    # return 302 https://authentik.company/outpost.goauthentik.io/start?rd=$scheme://$http_host$request_uri;
}

I've provided a screen shot below when RX Resume Server is also protected behind Authentik with the code snippet provided above. When this happens, in the snapshot you'll see that I get a message at the login page for RX Resume Client that logging into the server failed. I get a "CORS failed" message.

image

For reference, here's my docker compose for RX Resume Client so you can see my setup if useful. I have two separate domains, one for RX Resume Client (resume.domainname.com) and one for RX Resume Server (resumesvr.domainname.com).

version: "3.9"
services:
  resume-db:
    image: postgres
    container_name: rxresume_postgres
    hostname: resume-db
    security_opt:
      - no-new-privileges:true
    healthcheck:
      test: ["CMD", "pg_isready", "-q", "-d", "${DB_NAME}", "-U", "${DB_USER}"]
      interval: 10s
      timeout: 5s
      retries: 5
    user: 1032:100
    volumes:
      - /volume1/docker/rxresumev3/db:/var/lib/postgresql/data
    environment:
      POSTGRES_DB: ${DB_NAME}
      POSTGRES_USER: ${DB_USER}
      POSTGRES_PASSWORD: ${DB_PW}
    restart: always
    networks:
      - rxresume-internal

  resume-server:
    image: amruthpillai/reactive-resume:server-latest
    container_name: rxresume_server
    hostname: resume-server
    security_opt:
      - no-new-privileges:true
    healthcheck:
      test: curl -fSs http://localhost:3100/health || exit 1
      interval: 30s
      timeout: 5s
      retries: 3
    ports:
      - 8661:3100
    volumes:
      - /volume1/docker/rxresumev3/exports:/app/server/dist/assets/exports
      - /volume1/docker/rxresumev3/uploads:/app/server/dist/assets/uploads
    environment:
      - TZ=EST
      - PUBLIC_URL=https://${SERVER_HOSTNAME}              # URL that app is accessible and used in features like link sharing and auth redirection. This points only to client app as server would be running on port 3100 always. Ex, localhost:3000
      - PUBLIC_SERVER_URL=https://${SERVER_URL}       # URL through which server is accessible and is used when export PDF functionality is used within the app and has to reach out to the server. Ex, localhost:3100
      - POSTGRES_DB=${DB_NAME}
      - POSTGRES_USER=${DB_USER}
      - POSTGRES_PASSWORD=${DB_PW}
      - SECRET_KEY=${SECRET_KEY}    # Unique key, randomly generated string that is used for client-server communication. Use random.org random string generator to generate a long unique string
      - POSTGRES_HOST=resume-db
      - POSTGRES_PORT=5432
      - JWT_SECRET=${JWT_KEY}   # used for email/password authentication to hash + salt passwords stored in the database so they are unreadable
      - JWT_EXPIRY_TIME=604800                      # length of time (milliseconds) the JWT token should be valid for. Shorter value means the user has to login more often
      - MAIL_FROM_NAME=${EMAIL_NAME}
      - MAIL_FROM_EMAIL=${SMTP_FROM_EMAIL}
      - MAIL_HOST=smtp.gmail.com
      - MAIL_PORT=587
      - MAIL_USERNAME=${SMTP_USER}
      - MAIL_PASSWORD=${SMTP_PW}
    restart: always
    networks:
      - rxresume-internal
      - reverseproxy-nw
    depends_on:
      resume-db:
        condition: service_started

  resume-client:
    image: amruthpillai/reactive-resume:client-latest
    container_name: rxresume_client
    hostname: rxresume
    security_opt:
      - no-new-privileges:true
    healthcheck:
      test: curl -fSs 127.0.0.1:3000 || exit 1
      interval: 30s
      timeout: 5s
      retries: 3
    ports:
      - 8662:3000
    environment:
      - TZ=EST
      - PUBLIC_URL=https://${SERVER_HOSTNAME}
      - PUBLIC_SERVER_URL=https://${SERVER_URL}
      # - PUBLIC_FLAG_DISABLE_SIGNUPS=false
    restart: always
    networks:
      - rxresume-internal
      - reverseproxy-nw
    depends_on:
      resume-server:
        condition: service_healthy

networks:
  rxresume-internal:
  reverseproxy-nw:
    external: true

Product Flavor

-Self Hosted on Synology NAS

Expected behavior

I expect Authentik to be able to authenticate me first and then alllow me to continue on to login to the RX Resume service where I can then use the resume builder as normal. I can currently do this when I just use NPM to reverse proxy but when I want to authenticate with Authentik as a separate third party authenticator, then I run into problems using the RX Resume service.

xorgxx commented 1 year ago

and ?