JWT Authentication fails with "token required" (Debian 10)

Hi,
we are trying to set up a configuration with jitsi-meet and JWT authentication on a Debian 10 machine. We installed jitsi-meet by following the self hosting guide and it’s working without problems, but we enabled the JWT token following the JWT Authentication guide we got the following error on the browser dev console

JWT error: token required

this is coming presumably from the following request which contains a token under the correct query parameter

https://jitsi.mydomain/http-bind?room=test&token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImppdHNpL2N1c3RvbV9rZXlfbmFtZSJ9.eyJjb250ZXh0Ijp7InVzZXIiOnsibmFtZSI6IkpvaG4gRG9lIiwiZW1haWwiOiJqZG9lQGV4YW1wbGUuY29tIiwiaWQiOiJhYmNkOmExYjJjMy1kNGU1ZjYtMGFiYzEtMjNkZS1hYmNkZWYwMWZlZGNiYSJ9LCJncm91cCI6ImExMjMtMTIzLTQ1Ni03ODkifSwiYXVkIjoiaml0c2kiLCJpc3MiOiJteV9hcHBfaWQiLCJzdWIiOiJqaXRzaS5teWRvbWFpbiIsInJvb20iOiIqIiwiZXhwIjoxODAwMDA2OTIzfQ.q6_vpBBbK30Ug4fOHi8l4yg-8LFzhJ9hS3nC6AEZCLw

and the response is the following

token required

In the prosody.log file we can see the following error is triggered in token/util.lib.lua
Error verifying token err:not-allowed, reason:token required

We were using prosody 0.11.2 with the trunk patched to version 1nightly1377-1~buster, we also tried upgrading to version 0.11.9 with no results.

We also debugged the mod_auth_token.lua adding some logs and we noticed that in the function init_session(event) is never called when someone tries to join a room by using the token, we are thinking that, for some reason, the hook on bosh-session is never really called.

We went through the configuration steps several times to make sure that we did everything correctly and it appears so. our host configuration is the the following:

VirtualHost "jitsi.mydomain"
    -- enabled = false -- Remove this line to enable this host
    authentication = "token";
    -- Properties below are modified by jitsi-meet-tokens package config
    -- and authentication above is switched to "token"
    app_id="my_app_id";
    app_secret="my_secret";
    allow_empty_token = false;
    -- Assign this host a certificate for TLS, otherwise it would use the one
    -- set in the global section (if any).
    -- Note that old-style SSL on port 5223 only supports one certificate, and will always
    -- use the global one.
    ssl = {
        key = "/etc/prosody/certs/jitsi.mydomain.key";
        certificate = "/etc/prosody/certs/jitsi.mydomain.crt";
    }
    av_moderation_component = "avmoderation.jitsi.mydomain"
    speakerstats_component = "speakerstats.jitsi.mydomain"
    conference_duration_component = "conferenceduration.jitsi.mydomain"
    -- we need bosh
    modules_enabled = {
        "bosh";
        "pubsub";
        "ping"; -- Enable mod_ping
        "speakerstats";
        "external_services";
        "conference_duration";
        "muc_lobby_rooms";
        "av_moderation";
	"presence_identity";
    }
    c2s_require_encryption = false
    lobby_muc = "lobby.jitsi.mydomain"
    main_muc = "conference.jitsi.mydomain"
    -- muc_lobby_whitelist = { "recorder.jitsi.mydomain" } -- Here we can whitelist jibri to enter lobby enabled rooms

Any idea or help on this matter?

1 Like

As per lib-jitsi-meet/tokens.md at master · jitsi/lib-jitsi-meet · GitHub , the query parameter should be jwt=, not token=.

If you look carefully that is the http-bind call from the dev tools’ network of the browsers, not the url used to start the conference. The url was correctly formatted with the jwt parameter:

https://jitsi.mydomain/test?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImppdHNpL2N1c3RvbV9rZXlfbmFtZSJ9.eyJjb250ZXh0Ijp7InVzZXIiOnsibmFtZSI6IkpvaG4gRG9lIiwiZW1haWwiOiJqZG9lQGV4YW1wbGUuY29tIiwiaWQiOiJhYmNkOmExYjJjMy1kNGU1ZjYtMGFiYzEtMjNkZS1hYmNkZWYwMWZlZGNiYSJ9LCJncm91cCI6ImExMjMtMTIzLTQ1Ni03ODkifSwiYXVkIjoiaml0c2kiLCJpc3MiOiJteV9hcHBfaWQiLCJzdWIiOiJqaXRzaS5teWRvbWFpbiIsInJvb20iOiIqIiwiZXhwIjoxODAwMDA2OTIzfQ.q6_vpBBbK30Ug4fOHi8l4yg-8LFzhJ9hS3nC6AEZCLw

The application (the standard jitsi-meet web application) then does the magic and transforms the jwt parameter in the “token” paramater when the http-bind call is made

Can you try with a token created on jitok?

Fill only secret and aud fields.

I tried with jitok with only the secret and aud fields, instead of jwt.io. I got the same error and a parsing error on top of that, in the console log:

[connection.js] CONNECTION FAILED: connection.passwordRequired
[features/base/conference] JWT error: token required
[features/base/conference] JWT parsing error: Array [ “- invalid nbf value”, “- context object is missing from the payload” ]
[features/base/connection] <h/</</<>: connection.passwordRequired

edit: if I fill in the name and the email the error in the third line is:
JWT parsing error: Array [ “- invalid nbf value”]

Apparently we are able to make the token work by changing

module:hook("bosh-session", init_session);
module:hook("websocket-session", init_session);

with

module:hook_global("bosh-session", init_session);
module:hook_global("websocket-session", init_session);

in prosody-plugins/mod_auth_token.lua and now everything’s working.
Why this is happening? Did we miss something in the configuration or is it a bug?

Did you enable token_verification for conference muc?

Yes ,that was configured correctly to begin with

So this is what we found.

The process worked out of the box by installing the newer version of prosody (v. 0.11.9) on a clean system.
When we followed the guide installing the last version of prosody-trunk (patching prosody with the newer 1nightly1377-1~buster) it did not work.

We digged into the jitsi-meet-tokens pacakge and we found this snippet


                PR10_INSTALL_CHECK="$(dpkg-query -f '${Status}' -W 'prosody-0.10' 2>/dev/null | awk '{print $3}' || true)"
                PRTRUNK_INSTALL_CHECK="$(dpkg-query -f '${Status}' -W 'prosody-trunk' 2>/dev/null | awk '{print $3}' || true)"
                PR_VER_INSTALLED=$(dpkg-query -f='${Version}\n' --show prosody  2>/dev/null || true)
                if [ "$PR10_INSTALL_CHECK" = "installed" ] \
                    || [ "$PR10_INSTALL_CHECK" = "unpacked" ] \
                    || [ "$PRTRUNK_INSTALL_CHECK" = "installed" ] \
                    || [ "$PRTRUNK_INSTALL_CHECK" = "unpacked" ] \
                    || dpkg --compare-versions "$PR_VER_INSTALLED" lt "0.11" ; then
                    sed -i 's/module:hook_global(/module:hook(/g' /usr/share/jitsi-meet/prosody-plugins/mod_auth_token.lua
                fi

So apparently if you have prosody-trunk not installed but only unpacke you will not have the global hooks and the token authentication it will not work.

we fixed that by doing this fix

I think the installer should be modified to take into account prosody-trunk’s version and make the substitution only if the trunk is unpacked and no prosody 11 is installed (or if the trunk is unpacked and installed). What do you think?

That line is no longer valid as we introduced jitsi-meet/mod_jitsi_session.lua at master · jitsi/jitsi-meet · GitHub

Why do you need trunk?

We should drop the trunk logic we used very old trunk and taking care of all cases … But now anything 0.11 works just fine …

We followed what was written in the tutorial, what was a bit confusing for us is that it’s not clear that with the newer versions of prosody we should not have installed the trunk. From the phrasing it looks like patching the trunk is a needed step:

apt-get install jitsi-meet-tokens

Proceed to “Patching Prosody” section to finish configuration.

Yep, that needs some changes.

Fixed Drops old prosody versions from the tokens instructions by damencho · Pull Request #1650 · jitsi/lib-jitsi-meet · GitHub

1 Like

Perhaps it’s worth deleting this line (highlighted) so someone installing for the first time is not confused searching for a “Patching Prosody” section.

Ups. Thanks, will do

@Freddie does this sound better, wdyt?

2 Likes

This works. Fixes the potential confusion the previous line could have caused. Thanks! :+1:t5:

Thanks!
Now it looks much more clear indeed!

1 Like