Donkie / Spoolman

Keep track of your inventory of 3D-printer filament spools.
MIT License
920 stars 84 forks source link

Add authentication to API #229

Open Forceu opened 9 months ago

Forceu commented 9 months ago

As I don't want to run spoolman on the same system that contains my Klipper installation, I am hosting it on my home server. Securing the frontend is done by integrating Authelia, which makes it very easy. Unfortunately there is no way to secure the API.

It would be great if there was an option to require an API key. The most basic implementation could be a unmutable key supplied by an environment variable on the Spoolman server / container. A better but more work intensive way would be an interface to manage API keys.

Although I haven't looked much into the code yet, I would most likely be able to implement the first option myself. Please let me know your thoughts on that regard

rufinus commented 9 months ago

I'm using this:

Apache ReverseProxy with SSL Termination:

<VirtualHost *:443>
        ServerName spoolmanager.mydomain.tld

        ProxyPass / http://localhost:7912/
        ProxyPassReverse / http://localhost:7912/

        <Location />
        AuthType Basic
        AuthName "Restricted Content"
        AuthUserFile /etc/apache2/.htpasswd
        Require valid-user
        </Location>

        Header always set X-Content-Type-Options "nosniff"
        Header always set X-XSS-Protection "1; mode=block"
        Header always set Referrer-Policy "strict-origin-when-cross-origin"
        Header always set X-Frame-Options "SAMEORIGIN"
</VirtualHost>

In Moonraker.conf:

[spoolman]
server: https://myuser:mypassword@spoolmanager.mydomain.tld
Donkie commented 9 months ago

As I don't want to run spoolman on the same system that contains my Klipper installation, I am hosting it on my home server. Securing the frontend is done by integrating Authelia, which makes it very easy. Unfortunately there is no way to secure the API.

It would be great if there was an option to require an API key. The most basic implementation could be a unmutable key supplied by an environment variable on the Spoolman server / container. A better but more work intensive way would be an interface to manage API keys.

Although I haven't looked much into the code yet, I would most likely be able to implement the first option myself. Please let me know your thoughts on that regard

As rufinus said, you can use other services to create a secured gateway. However, a simple API-key configurable as an environment variable would be simple and effective. Care needs to be taken however in how this would interact with the web client, how should it inject the API key?

mawoka-myblock commented 9 months ago

As I don't want to run spoolman on the same system that contains my Klipper installation, I am hosting it on my home server. Securing the frontend is done by integrating Authelia, which makes it very easy. Unfortunately there is no way to secure the API. It would be great if there was an option to require an API key. The most basic implementation could be a unmutable key supplied by an environment variable on the Spoolman server / container. A better but more work intensive way would be an interface to manage API keys. Although I haven't looked much into the code yet, I would most likely be able to implement the first option myself. Please let me know your thoughts on that regard

As rufinus said, you can use other services to create a secured gateway. However, a simple API-key configurable as an environment variable would be simple and effective. Care needs to be taken however in how this would interact with the web client, how should it inject the API key?

Create an an endpoint where one can log in using username/password, as provided in the .env and return a short-lived api-key in a cookie. Add an option in the user interface to generate long-lived API-keys. This could be realized using JWTs.

jmceara commented 7 months ago

Just for information, just proxy doesn't work....we need websockets to moonraker work. This is my working configuration for remote/centralized spoolman with SSL termination and basic auth password:

<VirtualHost <IP>:443>
        ServerName spoolman.mydomain
        ServerAdmin webmaster@spoolman.mydomain
        UseCanonicalName Off

        CustomLog /var/log/apache2/domlogs/spoolman.mydomain.ssl.bytes bytes
        CustomLog /var/log/apache2/domlogs/spoolman.mydomain.ssl.log combined
        ErrorLog /var/log/apache2/domlogs/spoolman.mydomain.ssl.error.log

        <Location />
                AuthType Basic
                AuthName "Restricted Content"
                AuthUserFile /etc/apache2/.htpasswd-spoolman
                Require valid-user
        </Location>

        RewriteEngine on
        RewriteCond %{HTTP:Upgrade} websocket [NC]
        RewriteCond %{HTTP:Connection} upgrade [NC]
        RewriteRule ^/?(.*) "ws://127.0.0.1:7912/$1" [P,L]
        ProxyPass / http://127.0.0.1:7912/
        ProxyPassReverse / http://127.0.0.1:7912/
        LimitRequestBody 0
        ProxyRequests off

         SSLCertificateFile /etc/letsencrypt/live/spoolman.mydomain/fullchain.pem
         SSLCertificateKeyFile /etc/letsencrypt/live/spoolman.mydomain/privkey.pem
         Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
rufinus commented 7 months ago

@jmceara thanks, noticed that connection was failing, after some printers got their moonraker update.

xpert13 commented 5 months ago

I've used nginx container for adding basic auth: https://github.com/xpert13/Spoolman-with-basic-auth