Coder Social home page Coder Social logo

marcelcoding / jitsi-openid Goto Github PK

View Code? Open in Web Editor NEW
25.0 2.0 4.0 362 KB

Jitsi OpenID is an authentication adapter that allows Jitsi to authorize users with OpenID Connect.

License: GNU Affero General Public License v3.0

Dockerfile 3.19% Rust 79.94% Nix 16.88%
jitsi oidc auth jwt docker openid-connect axum oauth2 rust

jitsi-openid's Introduction

Jitsi OpenID

Jitsi OpenID is an authentication adapter to provide jitsi the ability to use single sign on via OpenID Connect.

Deployment

This guide is based of the docker setup from jitsi.

This image is available in the GitHub Container Registry:

ghcr.io/marcelcoding/jitsi-openid:latest

Docker "run" Command

docker run \
  -p 3000:3000 \
  -e JITSI_SECRET=SECURE_SECRET \
  -e JITSI_URL=https://meet.example.com \
  -e JITSI_SUB=meet.example.com \
  -e ISSUER_URL=https://id.example.com \
  -e BASE_URL=https://auth.meet.example.com \
  -e CLIENT_ID=meet.example.com \
  -e CLIENT_SECRET=SECURE_SECRET \
  --rm \
  ghcr.io/marcelcoding/jitsi-openid:latest

Docker Compose

# docker-compose.yaml

# ...

services:

  # ...

  jitsi-openid:
    image: ghcr.io/marcelcoding/jitsi-openid:latest
    restart: always
    environment:
      - 'JITSI_SECRET=SECURE_SECRET'             # <- shared with jitsi (JWT_APP_SECRET -> see .env from jitsi),
      #    secret to sign jwt tokens
      - 'JITSI_URL=https://meet.example.com'     # <- external url of jitsi
      - 'JITSI_SUB=meet.example.com'             # <- shared with jitsi (JWT_APP_ID -> see .env from jitsi),
      #    id of jitsi
      - 'ISSUER_URL=https://id.example.com'      # <- base URL of your OpenID Connect provider
      #    Keycloak: https://id.example.com/auth/realms/<realm>
      - 'BASE_URL=https://auth.meet.example.com' # <- base URL of this application
      - 'CLIENT_ID=meet.example.com'             # <- OpenID Connect Client ID
      - 'CLIENT_SECRET=SECURE_SECRET'            # <- OpenID Connect Client secret
        # - 'ACR_VALUES=password email'              # <- OpenID Context Authentication Context Requirements,
        #    space seperated list of allowed actions (OPTIONAL), see
        #    https://github.com/MarcelCoding/jitsi-openid/issues/122
        # - 'SCOPES=openid email jitsi'              # <- OpenID Scopes, space seperated list of scopes (OPTIONAL),
        #    default: openid email
        # - 'VERIFY_ACCESS_TOKEN_HASH=false          # <- explicitly disable access token hash verification (OPTIONAL),
        #    default: true
        # - 'SKIP_PREJOIN_SCREEN=false'              # <- skips the jitsi prejoin screen after login (default: true)
        # - 'GROUP=example'                          # <- Value for the 'group' field in the token
      #    default: ''
    ports:
      - '3000:3000'

# ...

To generate the JITSI_SECRET you can use one of the following command:

cat /dev/urandom | tr -dc a-zA-Z0-9 | head -c128; echo

NixOS

{
  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixos-23.11";
    jitsi-openid = {
      url = "github:MarcelCoding/jitsi-openid";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };

  outputs = { self, nixpkgs, jitsi-openid, ... }: {
    nixosConfigurations = {
      hostname = nixpkgs.lib.nixosSystem {
        modules = [
          jitsi-openid.nixosModules.default
          { nixpkgs.overlays = [ jitsi-openid.overlays.default ]; }
        ];
      };
    };
  };
}
# for an explanation see docker compose setup
services.jitsi-openid = {
  enable = true;
  settings = {
    package = pkgs.jitsi-openid;
    enable = true;
    listen = {
      addr = "::1";
      port = 6031;
    };
    jitsiSecretFile = "/run/secrets/jitsi-secret-file";
    jitsiUrl = "https://meet.domain.tld";
    jitsiSub = "meet.domain.tld";
    issuerUrl = "https://auth.domain.tld";
    baseUrl = "https://auth.meet.domain.tld";
    clientId = "auth.meet.domain.tld";
    clientSecretFile = "/run/secrets/client-secret-file";
    openFirewall = false;
  };
};

Jitsi Configuration

If you have problems understating this have a look here: #80

# for more information see:
# https://github.com/jitsi/docker-jitsi-meet/blob/master/env.example

# weather to allow users to join a room without requiring to authenticate
#ENABLE_GUESTS=1

# fixed
ENABLE_AUTH=1
AUTH_TYPE=jwt

# should be the same as JITSI_ID of jitsi-openid environment variables
JWT_APP_ID=meet.example.com
# should be the same as JITSI_SECRET of jitsi-openid environment variables
JWT_APP_SECRET=SECRET

# fixed values
JWT_ACCEPTED_ISSUERS=jitsi
JWT_ACCEPTED_AUDIENCES=jitsi

# auth.meet.example.com should be the domain name of jitsi-openid,
# `/room/{room}` is the endpoint that's jitsi redirecting the user to
# `{room}` is is a placeholder, where jitsi inserts the room name
# jitsi-openid should redirect the user after a successfully authentication
# !! it is recommend to use ALWAYS https e.g. using a reverse proxy !!
TOKEN_AUTH_URL=https://auth.meet.example.com/room/{room}

Jitsi JWTs

The JWTs are populated using the data returned by your IDP. This includes the user id, email and name.

The sub extracted from the prefered_username field, if that isn't preset the sub field is used.

The name is extracted from the name field, if that isn't preset a concatenation of given_name, middle_name and family_name is used. If all tree of them are also not present the prefered_username is used.

The affiliation is straight up passed, without any modifications or alternatives. It can be used to restrict the permissions a user has in a specific room in jitsi. See https://github.com/jitsi-contrib/prosody-plugins/tree/main/token_affiliation for more information.

The picture (avatar) URL is delegated from the IDP to Jitsi.

Translations aren't respected: #117 (comment)

License

LICENSE

jitsi-openid's People

Contributors

danielmalmgren avatar dependabot[bot] avatar marcelcoding avatar nwinkelstraeter avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

jitsi-openid's Issues

Unsupported version for ssl/tls certificate

Hi,

I am currently trying to use jitsi-openid to authenticate users on my Jitsi local server through a WebSSO LemonLDAP::NG. The LemonLDAP::NG is behind a HAProxy. Everything is dockerized, I mean, there is a docker container for jitsi-openid, four containers for Jitsi (web, prosody, jicofo and jvb), one for HAProxy and one for LemonLDAP::NG.

Request to the LemonLDAP::NG has to be done using the HTTPS protocol and there is a self-signed certificate associated to all requests pointing to port n°443 of the HAProxy.

When jitsi-openid starts, it requests LemonLDAP::NG to get its configuration through the URL https://auth.example.com/.well-known/openid-configuration. Nevertheless the request failed because it seems that jitsi-openid cannot validate the self-signed certificate.

2023-03-29T10:40:03.430277Z  INFO jitsi_openid: Using identity provider: https://auth.example.com/ and client-id: jitsi
2023-03-29T10:40:03.432345Z  WARN rustls::conn: Sending fatal alert BadCertificate    
Error: Request failed

Caused by:
    0: request failed
    1: error sending request for url (https://auth.example.com/.well-known/openid-configuration): error trying to connect: invalid peer certificate contents: invalid peer certificate: UnsupportedCertVersion
    2: error trying to connect: invalid peer certificate contents: invalid peer certificate: UnsupportedCertVersion
    3: invalid peer certificate contents: invalid peer certificate: UnsupportedCertVersion

Then jitsi-openid container crashes and tries to restart but never succeeds.

I created a repository to reproduce the issue https://github.com/jcabannes/jitsi-with-sso

This repository contains jitsi-openid folder because I added my self-signed certificate to the jitsi-openid container.

Moreover I verified in the jitsi-openid container if the certificate can be validated with openssl command : openssl s_client -connect auth.example.com:443 and it works (to keep container running, in Dockerfile, I used tail -f /dev/null command instead of /jitsi-openid/target/release/jitsi-openid).

Best regards

Improve README

Docker-compose version could be lowered. I my case 3.5 was ok without any change in formating.

If found it hard to get what is TOKEN_AUTH_URL=https://auth.meet.example.com/room/{room}

https://auth.meet.example.com part can be anything. Like https://jitsi.example.com:9999
But '/room/{room}' part must exist.
If this adapter and id provider are set up properly https://jitsi.example.com:9999/room/anything should redirect to provider and back to Jitsi.
And modern browsers can interfere in redirections changing http to https so it is highly recomended to setup reverse proxy with SSL for this container.

Group in context is null

Hello,

I am currently trying to get recordings in jitsi working with a proper participants list in the metadata.json that jibri creates.
This requires the mod_presence_identity prosody plugin to be enabled. (https://github.com/jitsi/lib-jitsi-meet/blob/master/doc/tokens.md#retrieve-token-identifiers-data)

That plugin does not accept any null values in the context and just crashes. (See note at the end of the linked paragraph).

I use this with authentik and it does send an affiliation or avatar. I fixed this simply by setting some dummy values using a custom scope mapping and adding that scope to the SCOPES variable.

However it looks like the groups value is always set to None here. So I can't set it with a scope mapping.

I tried simply removing group from the context and everything still works and mod_presence_identity does not crash anymore. Yay :D

I see that groups are part of jitsi expected token structure, though.
So while just removing them works, a way to somehow influence the value of group would be nice. Maybe with in environment variable or with with the IDP somehow.

Thanks, this project is really helpful. :)

Empty string as name

Hi.
I'm struggling with another really strange problem. For some of my users the jwt end up having an empty string as name. I have been digging deep into the problem and established that these users get given_name and family_name in their openid userinfo like everybody else, I can't seem to find any difference between the users that work and those that don't.

Questions:

  1. Can you see ANY scenario that would end up with an empty name?
  2. Is there any way of increasing log output to be able to actually follow what's happening under the hood?

This is what the decoded data portion of the jwt looks like for these users:
{
"context": {
"user": {
"id": "5i55fx32r9mo",
"email": "[email protected]",
"affiliation": null,
"name": "",
"avatar": null
},
"group": null
},
"aud": "jitsi",
"iss": "jitsi",
"sub": "",
"room": "
",
"iat": 1662698372,
"exp": 1662784772
}

Add functionality for configuring acr_values

The current implementation does not provide a means to send an authentication context.

This is described in OpenID Connect Core 1.0 incorporating errata set 1

The optional value is described in section 3.1.2.1. Authentication Request.

acr_values
OPTIONAL. Requested Authentication Context Class Reference values. Space-separated string that specifies the acr values that the Authorization Server is being requested to use for processing this Authentication Request, with the values appearing in order of preference. The Authentication Context Class satisfied by the authentication performed is returned as the acr Claim Value, as specified in Section 2. The acr Claim is requested as a Voluntary Claim by this parameter.

When an authentication context is not sent with the request it is up to the IDP to determine the contract to execute, and default this will be a Username/Password type.
By adding the acr_values parameter one can explicitly select a different contract to authenticate with, for example Username/Password/2FA.

  • Glowsome

Skip pre join screen after auth

We have the prejoin screen enabled.  When we are authenticated we want to disable that screen.

You can do it when you send the url to jitsi with adding #config.prejoinConfig.enabled=false to the url part. (there are quite a few options you can send along that way to also enable/disable buttons and more)

So we share the link to the room and we get to a prejoin screen. On that we have a button that will send you to the auth screen (Instead of using the i am moderator popup) and then you get back to the room.  IF we can specify that extra part in the url  you get straight in. As it is right now you get back to the prejoin page.

Email from @small1

Join required again after SSO Login

Hey, first thanks for your great plugin, it works very well for our small team of 13 with Authentik as the SSO-provider.

One of the two (minor) issues we're having is that after a user chooses to become moderator and completes the SSO dance, they are sent back to the pre-meeting screen, thus having to click "Join" again. That is mildly annoying, but not really a problem. Just thought I'd raise it here.

Best,
m

SSO-Login causes link with '/' to be shortened

Hey, first thanks for your great plugin, it works very well for our small team of 13 with Authentik as the SSO-provider.

The other of the two (minor) issues we're having is that while Jitsi allows us to use links like https://jitsi/foo/bar, after the SSO dance, /foo is stripped and the new moderator joins a room bar, which is not the same as the room foo/bar, and can lead to a lot of confusion.

No idea how to use this

Documentation is quite sparse and assumes a lot. There appears to be numerous variations in how to setup jitsi. What are the prereqs for this to work? I see no JWT anything digging through config files on a standard jitsi install. Is this some add-on? What are the additional subdomains referring to? I have a vanilla instance with zero subdomains that seems to be working out.

Having said all of that, I have no idea how to use this whatsoever. Please help me figure this out so I can send a PR to update the readme so other users don't get lost. Thank you

Invalid Id Token Nonce

Hi again.
I've bumped into another problem... I've finally got my idp to send correct id tokens (it turned out it never did because of a certificate problem here) but now when it gets to jitsi-openid I only get the response "Invalid Id Token Nonce".

I've checked that the functionality to return nonce in my idp works fine, if I manually send in a nonce I get the same nonce back in my id token, so it seems jitsi-openid handles this wrong in some way. Could you check in to it? One alternative would be if there was any way to disable the nonce verification entirely?

Login dialog does not work

Hi Marcel, thank you for this software!

Yesterday I built a test instance of latest Jitsi + jitsi-openid to hook Jitsi auth to our Keycloak.

The setup was easy and worked like a charm on my first attempt, but only when creating a room.

My setup allows for guests to enter an already existing room, ie:

ENABLE_GUESTS=1
ENABLE_AUTO_LOGIN=0
JWT_ALLOW_EMPTY=1
JICOFO_AUTH_TYPE=internal
JICOFO_AUTH_LIFETIME=100 milliseconds
PROSODY_AUTH_TYPE=jwt

With this setup, if I go to the 3 dot menu, my profile and hit "Login", when asked if I'm sure I want to abandon the conference and hit yes, nothing happens.

image

There were some recent changes (3 months ago) to this jitsi-meet code, so I wonder if something broke in the process, or my setup is not correct. https://github.com/jitsi/jitsi-meet/blob/master/react/features/authentication/components/web/LoginQuestionDialog.tsx

I also have problems to logout, but that would be for another issue, I guess.

Thanks in advance!

Add support for token_affiliation

I will be needing support for token affiliation in my jwt's. It would mean that if the incoming openid token contains an attribute named "affiliation" I would simply need jitsi-openid to put it in the jwt sent to Jitsi. That would be an easy fix, right?

Missing "moderator": "true" prop from claim

on the latest jitsi image the JWT token requires the
"isModerator": true prop to be set in case guest are allowed.
(a Moderator has to join first, then the guest can)

My ID (authentik) can provide that prop in the claim, but it needs to be passed on to the JWT.


... Ideally I generic solution can be found for future props.
Like take all the props in the claim and pass them on.
This would also allow to set e.g. avatar etc pp

{
    "context": {
        "user": {
            "avatar": "https://robohash.org/user1",
            "name": "user1",
            "email": "user1"
        }
    },
    "moderator": true,
    "aud": "jitsi",
    "iss": "5bX...",
    "sub": "meet.jitsi",
    "room": "*",
    "iat": 1701859693
    "nbf": 1701859693
    "exp": 1701859693
}

Add https listener

Hello. Thx for this adapter!
I think that readme needs some notice about SSL implementation. Like "don't forget to cover it in reverse proxy with SSL".
And may be you could add native SSL support like they did for Jitsi itself. Two env variables for keys would be nice.
And thx again ^)

Nbf prop missing in token

My self-hostec jitsi requires the property nbf to be set in the token. Otherwise it fails.

Sorry, you’re not allowed to join this call. Possible reasons: Invalid `nbf` value. 

If I edit the token manually and add nbf with the same value is iat, then it works.

Jitsi Version: stable-8138-1

Concatenating firstname and lastname

Hi.
I have one more small thing here that would make my solution perfect, wondering if you're willing to help?

Thing is, now it works like a charm for "normal" users here. My problem is that we will be having some external users that doesn't exist in our user directory, and they will log in e-identification. Among the info I can get for them I have no attribute for full name, but I have two attributes for firstname and lastname. Stupidly enough my idp doesn't have support for simply putting those values together into one attribute, so I have no way of sending their full name in the openid id token.

So what I'm wondering is if this would be possible: If there is no "name" in the openid info, instead check if there are a "firstname" and a "lastname" (or whatever, I can call them what I want in my end) and if there is, concatenate them with a space in between and use the result as name.

I started looking at it myself, but Rust really is a weird language, can't really get my head around it :-/

Invalid code on authorization

I'm implementing this against an idp. And we get as far as invalid code. It looks like it does fetch the token. But directly after says invalid code.

Ir is not clear on why it fails. We can see on the IDP that it seems to have fetched the token. And the token seems correct when we test it.

Last image tag 2.0.5 broken

Hi,

Thanks for this software,
FYI, the last tag 2.0.5 is broke

jitsi-jitsi-openid-1 | 2023-10-16T09:34:15.867128501Z /jitsi-openid/jitsi-openid: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found (required by /jitsi-openid/jitsi-openid)

Works with keycloak but not nextcloud

I had been using keycloak as as my openid provider but am trying to reduce the number of packages to keep up-to-date and because I also have nextcloud running for various other purposes and they have added openid to their bag of tricks, I'm trying to switch over. jitsi-openid is working perfectly with keycloak (thanks for that) but when I try to use it with nextcloud I successfully login and get returned to jitsikeycloak where I receive an error that simply states "Invalid token" there's nothing in the jitsi-openid logs at all and nothing that I can identify as useful info in the logs of the various docker containers running the jitsi-meet installation. Any help/insight would be great appreciated (but of course I understand if my inability to provide meaningful info means that there's nothing you can do).

Thanks,

Seth Green

Problems with Jitsi 7577

Hi.
You haven't by any chance tested jitsi-openid with Jitsi 7577? After upgrading I just get "You are not allowed to be here!" when I try to enter any room. In the Prosody log I get the following

prosody_1 | muc.meet.jitsi:token_verification error Token eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJjb250ZXh0Ijp7InVzZXIiOnsiaWQiOiJyZWRhY3RlZCIsImVtYWlsIjoicmVkYWN0ZWQiLCJhZmZpbGlhdGlvbiI6bnVsbCwibmFtZSI6IkRhbmllbCBNYWxtZ3JlbiIsImF2YXRhciI6bnVsbH0sImdyb3VwIjpudWxsfSwiYXVkIjoiaml0c2kiLCJpc3MiOiJqaXRzaSIsInN1YiI6ImppdHNpX3Rlc3RfYXBwX2lkIiwicm9vbSI6IioiLCJpYXQiOjE2NjAxMzEyNzEsImV4cCI6MTY2MDIxNzY3MX0.JGaMHRalHIrLxoFdMA6FONwJXqYwv2k1bwKmZeaHMpg not allowed to join: [email protected]/5a792dc6

Everything works fine when rolling back to 7439, so I guess something happened between those versions.

Missing field keys on start

Hi, I'm working to get this implemented between a self-hosted Jitsi and Authentik IDP. I believe I have the compose and env files setup as required but running into this error on starting this container:

jitsi-openid-jitsi-openid-1  | 2023-03-03T05:15:32.709222Z  INFO jitsi_openid: Using identity provider: https://"mydomain.xyz"/application/o/jitsi/ and client-id: "client_string_matching_IDP"
jitsi-openid-jitsi-openid-1  | Error: Failed to parse server response
jitsi-openid-jitsi-openid-1  |
jitsi-openid-jitsi-openid-1  | Caused by:
jitsi-openid-jitsi-openid-1  |     0: .: missing field `keys` at line 1 column 2
jitsi-openid-jitsi-openid-1  |     1: missing field `keys` at line 1 column 2
jitsi-openid-jitsi-openid-1 exited with code 0

When I manually browse to https://"mydomain.xyz"/application/o/jitsi/.well-known/openid-configuration I get the expected JSON output. Appreciate any help.

Returning to correct room after authentication

Hi.
After hours and hours of struggling (starting to feel like this guy) I think I almost have got oidc authentication working with Jitsi, but I'm stuck and hope to get some help here. I have got this far:

  1. When trying to enter a room I get redirected to my auth server
  2. I log in
  3. I'm sent back including the oidc code
    However, when I'm sent back I don't end up in the room I tried to enter but back on the main page. How is the flow supposed to work? Shouldn't jitsi after successful login do the redirection into the room?

Also I don't understand the TOKEN_AUTH_URL parameter. To get it working this far I have set it to the following:
https://idp.redacted/https/api/rest/v3.0/oauth/authorize?client_id=qG4ZETXFGdc4Nj33ACW6&response_type=code&redirect_uri=https%3A%2F%2Fvideo.redacted&scope=openid
...but from the example on the readme I guess I should put the room somewhere here and I don't understand where and how. Is the auth server supposed to do something with the room name and return it to Jitsi so that it knows which room to enter?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.