Adds tokens.md.
This commit is contained in:
parent
b6ea819b2d
commit
503db36efd
|
@ -42,7 +42,7 @@ function JitsiConference(options) {
|
|||
*/
|
||||
JitsiConference.prototype.join = function (password) {
|
||||
if(this.room)
|
||||
this.room.join(password);
|
||||
this.room.join(password, this.connection.tokenPassword);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -16,14 +16,17 @@ function generateUserName() {
|
|||
* Creates new connection object for the Jitsi Meet server side video conferencing service. Provides access to the
|
||||
* JitsiConference interface.
|
||||
* @param appID identification for the provider of Jitsi Meet video conferencing services.
|
||||
* @param token secret generated by the provider of Jitsi Meet video conferencing services.
|
||||
* @param tokenPassword secret generated by the provider of Jitsi Meet video conferencing services.
|
||||
* The token will be send to the provider from the Jitsi Meet server deployment for authorization of the current client.
|
||||
* The format is:
|
||||
* passwordToken = token + "_" + roomName + "_" + ts
|
||||
* See doc/tokens.md for more info on how tokens are generated.
|
||||
* @param options Object with properties / settings related to connection with the server.
|
||||
* @constructor
|
||||
*/
|
||||
function JitsiConnection(appID, token, options) {
|
||||
function JitsiConnection(appID, tokenPassword, options) {
|
||||
this.appID = appID;
|
||||
this.token = token;
|
||||
this.tokenPassword = tokenPassword;
|
||||
this.options = options;
|
||||
this.xmpp = new XMPP(options);
|
||||
this.conferences = {};
|
||||
|
@ -38,8 +41,8 @@ JitsiConnection.prototype.connect = function (options) {
|
|||
options = {};
|
||||
|
||||
// If we have token provided use it as a password and generate random username
|
||||
if (this.token) {
|
||||
options.password = this.token;
|
||||
if (this.tokenPassword) {
|
||||
options.password = this.tokenPassword;
|
||||
if (!options.id) {
|
||||
options.id = generateUserName() + "@" + this.options.hosts.domain;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,151 @@
|
|||
Token authentication Prosody plugin
|
||||
==================
|
||||
|
||||
This plugin implements Prosody authentication provider that verifies client connection based on authentication token.
|
||||
It allows to use any external form of authentication with lib-jitsi-meet. Once your user authenticates you need to
|
||||
generate the token with formula described in "Token generation mechanism" and pass it to your client app. When it
|
||||
connects using valid token is considered authenticated by jitsi-meet system.
|
||||
|
||||
From XMPP perspective this is SASL PLAIN authentication where token is passed as a password. The username can be
|
||||
supplied by your application. By default it is generated randomly in lib-jitsi-meet. Keep in mind that JiCoFo is using
|
||||
"focus" as it's MUC nickname, so you should avoid allowing this name for other users.
|
||||
|
||||
### Token generation mechanism
|
||||
|
||||
Authentication token is SHA256 hash of the following string:
|
||||
|
||||
*roomName + ts + appId + appSecret*
|
||||
|
||||
- *roomName* - the name of the conference room(must be lowercase)
|
||||
|
||||
- *ts* - UTC token timestamp in milliseconds which indicates the time when token has been created
|
||||
|
||||
- *appId* - application identifier used to distinguish between applications that are using the system. It can be any random string if you're using only one application at a time.
|
||||
|
||||
- *appSecret* - application secret which should be known only to the token generator and Prosody server
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
roomName = angrywhalesgrowhigh
|
||||
|
||||
ts = 1446573136000 -- corresponds to 11/03/2015 @ 5:52pm (UTC)
|
||||
|
||||
appId = myTestApp
|
||||
|
||||
appSecret = blablabla
|
||||
```
|
||||
|
||||
Text to be hashed:
|
||||
|
||||
```
|
||||
angrywhalesgrowhigh1446573136000myTestAppblablabla
|
||||
```
|
||||
|
||||
The token is Sha256 hash of the text above:
|
||||
|
||||
```
|
||||
0daad82d1ad81c718d643b71b46793af2295bb20e3eb436079e9bbd130ba1ad9
|
||||
```
|
||||
|
||||
Once we have the token generated we concatenate it with timestamp and room name like described in "Token verification"
|
||||
section. It is passed as user's password during authentication process.
|
||||
|
||||
### Token verification
|
||||
|
||||
When user connects to Prosody then SASL PLAIN authentication is being used for token authentication purpose. Username is supplied by the application and in case of jitsi-meet it is randomly generated string(can be also overridden with *config.id* property). The password is a token plus name of the conference room and UTC timestamp in milliseconds:
|
||||
|
||||
```
|
||||
password = token + "_" + roomName + "_" + ts;
|
||||
```
|
||||
|
||||
The password for the example from "Token generation mechanism" section would look like this:
|
||||
|
||||
```
|
||||
0daad82d1ad81c718d643b71b46793af2295bb20e3eb436079e9bbd130ba1ad9_angrywhalesgrowhigh_1446573136000
|
||||
```
|
||||
|
||||
When user connects the authentication plugin first verifies the timestamp. By default the token is valid for 24 hours
|
||||
and it is compared against UTC timestamp returned by the server's system clock.
|
||||
|
||||
When the timestamp is fine the token is being verified. The name of the room and timestamp are extracted from the
|
||||
password. Application id and secret come from Prosody host config(see "Manual plugin configuration" section for detailed
|
||||
info). The hash computed by the plugin is compared with the one supplied as part of the user's password.
|
||||
|
||||
The token is also verified whenever users tries to create new MUC room. This prevents from creating multiple rooms using
|
||||
the same hash which may cause troubles in case it's stolen. Unless the user is an admin it must include it as part of
|
||||
the presence stanza that creates the room:
|
||||
|
||||
```xml
|
||||
<presence
|
||||
from='user1@example.com/desktop'
|
||||
to='angrywhalesgrowhigh@muc.example.com/somenickname'>
|
||||
<x xmlns='http://jabber.org/protocol/muc'/>
|
||||
<token xmlns='http://jitsi.org/jitmeet/auth-token'>
|
||||
0daad82d1ad81c718d643b71b46793af2295bb20e3eb436079e9bbd130ba1ad9_angrywhalesgrowhigh_1446573136000
|
||||
</token>
|
||||
</presence>
|
||||
```
|
||||
|
||||
### Lib-jitsi-meet options
|
||||
|
||||
When token authentication is used with *lib-jitsi-meet* the token is passed to *JitsiConference* constructor:
|
||||
|
||||
```
|
||||
var token = {token is provided by your application possibly after some authentication}
|
||||
var tokenPassword = token + "_" + roomName + "_" + ts;
|
||||
|
||||
JitsiMeetJS.init();
|
||||
|
||||
var connection = new JitsiMeetJS.JitsiConnection(APP_ID, tokenPassword, options);
|
||||
|
||||
connection.connect();
|
||||
```
|
||||
|
||||
### Jitsi-meet options
|
||||
|
||||
In order to start jitsi-meet conference with token you need to specify the token as URL param:
|
||||
```
|
||||
https://example.com/angrywhalesgrowhigh#config.token="0daad82d1ad81c718d643b71b46793af2295bb20e3eb436079e9bbd130ba1ad9_angrywhalesgrowhigh_1446573136000"
|
||||
```
|
||||
At current level of integration every user that joins the conference has to provide the token and not just the one who
|
||||
creates the room. It should be possible to change that by using second anonymous domain, but that hasn't been tested
|
||||
yet.
|
||||
|
||||
### Installing token plugin
|
||||
|
||||
Token authentication can be integrated automatically using Debian package install. Once you have jitsi-meet installed
|
||||
just install 'jitsi-meet-tokens' on top of it. In order to have it configured automatically at least version 721 of
|
||||
jitsi-meet is required which comes with special Prosody config template.
|
||||
```
|
||||
apt-get install jitsi-meet-token
|
||||
```
|
||||
|
||||
### Manual plugin configuration
|
||||
|
||||
Modify your Prosody config with these three steps:
|
||||
|
||||
1. Adjust *plugin_paths* to contain the path pointing to jitsi meet Prosody plugins location. That's where plugins are copied on *jitsi-meet-token* package install. This should be included in global config section(possibly at the beginning of your host config file).
|
||||
|
||||
```lua
|
||||
plugin_paths = { "/usr/share/jitsi-meet/prosody-plugins/" }
|
||||
```
|
||||
|
||||
2. Under you domain config change authentication to "token" and provide application ID, secret and optionally token lifetime:
|
||||
|
||||
```lua
|
||||
VirtualHost "jitmeet.example.com"
|
||||
authentication = "token";
|
||||
allow_unencrypted_plain_auth = true; -- required for token authentication to work
|
||||
app_id = example_app_id; -- application identifier
|
||||
app_secret = example_app_secret; -- application secret known only to your token
|
||||
-- generator and the plugin
|
||||
token_lifetime=86400000; -- (optional) token lifetime in milliseconds
|
||||
```
|
||||
|
||||
3. Enable token verification plugin in your MUC component config section:
|
||||
|
||||
```lua
|
||||
Component "conference.jitmeet.example.com" "muc"
|
||||
modules_enabled = { "token_verification" }
|
||||
```
|
|
@ -87,17 +87,17 @@ ChatRoom.prototype.initPresenceMap = function () {
|
|||
});
|
||||
};
|
||||
|
||||
ChatRoom.prototype.join = function (password, token) {
|
||||
ChatRoom.prototype.join = function (password, tokenPassword) {
|
||||
if(password)
|
||||
this.password = password;
|
||||
var self = this;
|
||||
this.moderator.allocateConferenceFocus(function()
|
||||
{
|
||||
self.sendPresence(token);
|
||||
self.sendPresence(tokenPassword);
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
ChatRoom.prototype.sendPresence = function (auth_token) {
|
||||
ChatRoom.prototype.sendPresence = function (tokenPassword) {
|
||||
if (!this.presMap['to']) {
|
||||
// Too early to send presence - not initialized
|
||||
return;
|
||||
|
@ -117,9 +117,9 @@ ChatRoom.prototype.sendPresence = function (auth_token) {
|
|||
pres.c('c', this.connection.caps.generateCapsAttrs()).up();
|
||||
}
|
||||
|
||||
if (auth_token) {
|
||||
if (tokenPassword) {
|
||||
pres.c('token', { xmlns: 'http://jitsi.org/jitmeet/auth-token'})
|
||||
.t(auth_token).up();
|
||||
.t(tokenPassword).up();
|
||||
}
|
||||
|
||||
parser.JSON2packet(this.presMap.nodes, pres);
|
||||
|
|
Loading…
Reference in New Issue