Long Lived Access Token via URL or Body?

Hi,

I’m trying to push a binary sensor via the http rest method from a 2N door station which has limited tools for responding to events.

It allows me to set a URL, Username & Password (for challenge auth), method (I know POST is required), type (set to application/json) and text which I have set to the JSON for the sensor I want to post.

The issue I have is with the auth, I’ve created a long lived access token, however, I don’t have the ability to set a header for this in the post from the 2N device. Is there a way to pass it in the URL or the JSON?

Thanks

The short answer is no.

You’re going to need something that can re-write the request from the door station into the format that HA requires.

Thought I might be out of luck…

I have my HA behind an NginX reverse proxy, I wonder if I can capture the request (with the LLAT in the URL) from the door station and then re-write that as a header…?

You should be able to do so, nginx supports regex match groups in URI pattern.
See the documentation for ngx_http_proxy_module for details. I haven’t done something like this before so please don’t take me by word that this need to work!

But please note: If you’re unable to set a widely used custom header I wouldn’t trust your door station to use proper TLS encryption. You should check if your requests uses proper encryption and can’t be downgraded or otherwise eavesdropped!

So I’ve finally got this working… For those who are interested in how I got around my Door Station limitations using NginX reverse proxy, please read on…

server {
    server_name myserverurl.com; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/myserverurl.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/myserverurl.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

    location / {
        proxy_pass http://192.168.4.249:8123;
        proxy_set_header Host $host;
        proxy_redirect http:// https://;
        proxy_http_version 1.1;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_set_header X-Forwarded-Proto $scheme;

Everything up to here is as was with regards to the nginx configuration. But because my door station can’t set custom headers, I planned to pass the long lived access token (llat) as part of the querystring, so I created the following configuration which follows on directly from above. In simple terms, I read any existing Authorisation header that came from the client (so as not to break any normal calls that are able to set the Authorisation header) into a variable. Then if I see a query string argument for the value llat, I overwrite the variable with the query string value.

        #Read any Authorisation header already received from the client as a default
        set $my_client_auth_header $http_authorization;

        #Conditionally overwrite the header values it if there is a querystring value for llat (long lived access token)
        if ($arg_llat != '') {
            set $my_client_auth_header "Bearer $arg_llat";
        }

Then unfortunately after getting that all tested with Postman, I updated the url that the door station calls when the gate opens only to discover that it crashes if you put a long url in!!!

So I then basically had to take an approach which I didn’t want to originally as it requires storing a llat in the configuration file which I don’t want accidentally applied to any rogue incoming requests. Therefore, I have added a check on the client sending IP to make sure it’s come from the door station internally and if that matches, then to overwrite the Authorisation variable with the fixed llat value.

        #Conditionally overwrite the header value if the call came from the DS2 door station (which can't support long URL's or headers!!!)
        if ($remote_addr = "192.168.4.55") {
            set $my_client_auth_header "Bearer my_long_lived_access_token"
        }

Finally set an authorisation header in the proxied request using the value from the variable.

        proxy_set_header Authorization $my_client_auth_header;
    }
}

Issues that I see with this currently, is that if no Authorisation token was sent in the originating request, my changes here will add one regardless, although it will be blank if no llat is specified in the query string. Thus far I haven’t seen any negative effects from this, but it has only been in place for about 8 hours.

Additionally, the process above prefers a given query string llat over the posted header authorisation, this may not be desirable in all cases, but I think it’s obscure enough for my purposes.

Hopefully that helps someone. If anyone has any comments / suggestion, happy to receive feedback, it’s the first time I’ve done anything in Nginx beyond the standard setup.

For clarify, if you’re looking to repurpose this, cut and paste each of the code sections above as one whole block into your nginx config for your server to define the complete server section. Obviously the initial piece that defines the site should match what you have already so please edit to suit.

Cheers

1 Like

Some serious nginx deep dive gratulations :slight_smile:

Long URL support would be better from a security perspective. You might make sure no one can asign itself the IP-Address of your door station, you may can force its assignment to a specific port on your router / switch.

Thanks for the kudos, it’s nice to accomplish something!

I agree about preferring the url approach, I got that working as my goto solution before discovering the door station shortcomings.

I need to find some time to break down my network into vlans soon as I’m running out of room and also want to isolate a lot of these iot devices so I’ll look to lock that down a bit more as you suggested.

Thanks

I’m not 100% on this but I think you can only access the apis with a llat not the user ui itself.