This article presents configuration options available to the administrator and describe how to set Tigase server up to use user accounts data from a different database.
The first thing to know is that Tigase server always opens 2 separate connections to the database. One connection is used for user login data and the other is for all other user data like the user roster, vCard, private data storage, privacy lists and so on…
In this article we still assume that Tigase server keeps user data in it’s own database and only login data is retrieved from the external database.
At the moment Tigase offers following authentication connectors:
mysql
, pgsql
, derby
- standard authentication connector used to load user login data from the main user database used by the Tigase server. In fact the same physical implementation is used for all JDBC databases.drupal
- is the authentication connector used to integrate the Tigase server with Drupal CMS.tigase-custom
- is the authentication connector which can be used with any database. Unlike the 'tigase-auth' connector it allows you to define SQL queries in the configuration file. The advantage of this implementation is that you don’t have to touch your database. You can use either simple plain SQL queries or stored procedures. The configuration is more difficult as you have to enter carefully all SQL queries in the config file and changing the query usually involves restarting the server. For more details about this implementation and all configuration parameters please refer to Tigase Custom Auth documentation.tigase-auth
(DEPRECATED) - is the authentication connector which can be used with any database. It executes stored procedures to perform all actions. Therefore it is a very convenient way to integrate the server with an external database if you don’t want to expose the database structure. You just have to provide a set of stored procedures in the database. While implementing all stored procedures expected by the server might be a bit of work it allows you to hide the database structure and change the SP implementation at any time. You can add more actions on user login/logout without restarting or touching the server. And the configuration on the server side is very simple. For detailed description of this implementation please refer to Tigase Auth documentation.As always the simplest way to configure the server is through the config.tdsl
file. In the article describing this file you can find long list with all available options and all details how to handle it. For the authentication connector setup however we only need 2 options:
dataSource { 'default-auth' () { uri = 'database connection url' } } authRepository { default () { cls = 'connector' 'data-source' = 'default-auth' } }
For example if you store authentication data in a drupal
database on localhost
your settings would be:
dataSource { 'default-auth' () { uri = 'jdbc:mysql://localhost/drupal?user=user&password=passwd' } } authRepository { default () { 'data-source' = 'default-auth' } }
You have to use a class name if you want to attach your own authentication connector.
Default is:
authRepository { default { cls = 'tigase.db.jdbc.TigaseAuth' } }
In the same exact way you can setup connector for any different database type.
For example, drupal configuration is below
authRepository { default { cls = 'tigase.db.jdbc.DrupalWPAuth' } }
Or tigase-custom authentication connector.
authRepository { default { cls = 'tigase.db.jdbc.TigaseCustomAuth' } }
The different cls
or classes are:
tigase.db.jdbc.DrupalWPAuth
tigase.db.jdbc.JDBCRepository
You can normally skip configuring connectors for the default Tigase database format: mysql
, pgsql
and derby
, sqlserver
as they are applied automatically if the parameter is missing.
One more important thing to know is that you will have to modify authRepository
if you use a custom authentication connector. This is because if you retrieve user login data from the external database this external database is usually managed by an external system. User accounts are added without notifying Tigase server. Then, when the user logs in and tries to retrieve the user roster, the server can not find such a user in the roster database.
To keep user accounts in sync between the authentication database and the main user database you have to add following option to the end of the database connection URL: autoCreateUser=true
.
For example:
dataSource { default () { uri = 'jdbc:mysql://localhost/tigasedb?user=nobody&password=pass&autoCreateUser=true' } }
If you are interested in even further customizing your authentication connector by writing your own queries or stored procedures, please have a look at the following guides:
Tigase Auth connector is DEPRECATED as of version 8.0.0 and will be removed in future releases
The Tigase Auth connector with shortcut name: tigase-auth is implemented in the class: tigase.db.jdbc.TigaseAuth. It allows you to connect to any external database to perform user authentication. You can find more details how to setup a custom connector in the Custom Authentication Connectors guide.
To make this connector working you have to prepare your database to offer set of stored procedures for Tigase server to perform all the authentication actions. The best description is the example schema with all the stored procedures defined - please refer to the Tigase repositories for the schema definition files (each component has it’s dedicated schema). For example:
The absolute minimum of stored procedures you have to implement is:
TigUserLoginPlainPw
- to perform user authentication. The procedure is always called when the user tries to login to the XMPP server. This is the only procedure which must be implemented and actually must work.TigUserLogout
- to perform user logout. The procedure is always called when the user logouts or disconnects from the server. This procedure must be implemented but it can be empty and can do nothing. It just needs to exist because Tigase expect it to exist and attempts to call it.With these 2 above stored procedures you can only perform user login/logouts on the external database. You can’t register a user account, change user password or remove the user. In many cases this is fine as all the user management is handled by the external system.
If you however want to allow for account management via XMPP you have to implement also following procedures:
TigAddUserPlainPw
- to add a new user accountTigRemoveUser
- to remove existing user accountTigUpdatePasswordPlainPw
- to change a user password for existing accountThe Tigase Custom Auth connector with shortcut name: tigase-custom is implemented in the class: tigase.db.jdbc.TigaseCustomAuth. It allows you to connect to any external database to perform user authentication and use a custom queries for all actions.
You can find more details how to setup a custom connector in the Custom Authentication Connectors guide.
The basic configuration is very simple:
authRepository { default () { cls = 'tigase.db.jdbc.TigaseCustomAuth' 'data-source' = 'default-auth' } }
That’s it.
The connector loads correctly and starts working using predefined, default list of queries.
In most cases you also might want to define your own queries in the configuration file.
The shortest possible description is the following example of the content from the config.tdsl
file:
This query is used to check connection to the database, whether it is still alive or not
authRepository { default () { 'conn-valid-query' = 'select 1' } }
This is database initialization query, normally we do not use it, especially in clustered environment
authRepository { default () { 'init-db-query' = 'update tig_users set online_status = 0' } }
Below query performs user authentication on the database level. The Tigase server does not need to know authentication algorithm or password encoding type, it simply passes user id (BareJID) and password in form which was received from the client, to the stored procedure. If the authentication was successful the procedure returns user bare JID or null otherwise. Tigase checks whether the JID returned from the query matches JID passed as a parameter. If they match, the authentication is successful.
authRepository { default () { 'user-login-query' = '{ call TigUserLoginPlainPw(?, ?) }' } }
Below query returns number of user accounts in the database, this is mainly used for the server metrics and monitoring components.
authRepository { default () { 'users-count-query' = '{ call TigAllUsersCount() }' } }
The Below query is used to add a new user account to the database.
authRepository { default () { 'add-user-query' = '{call TigAddUserPlainPw(?, ?) }' } }
Below query is used to remove existing account with all user’s data from the database.
authRepository { default () { 'del-user-query' = '{ call TigRemoveUser(?) }' } }
This query is used for the user authentication if user-login-query
is not defined, that is if there is no database level user authentication algorithm available.
In such a case the Tigase server loads user’s password from the database and compares it with data received from the client.
authRepository { default () { 'get-password-query' = 'select user_pw from tig_users where user_id = ?' } }
Below query is used for user password update in case user decides to change his password.
authRepository { default () { 'update-password-query' = 'update tig_users set user_pw = ? where user_id = ?' } }
This query is called on user logout event. Usually we use a stored procedure which records user logout time and marks user as offline in the database.
authRepository { default () { 'update-logout-query' = 'update tig_users, set online_status = online_status - 1 where user_id = ?' } }
This configuration specifies what non-sasl authentication mechanisms to expose to the client
authRepository { default () { 'non-sasl-mechs' = [ 'password', 'digest' ] } }
This setting to specify what sasl authentication mechanisms expose to the client
authRepository { default () { 'sasl-mechs' = 'PLAIN,DIGEST-MD5' } }
Queries are defined in the configuration file and they can be either plain SQL queries or stored procedures. If the query starts with characters: { call
then the server assumes this is a stored procedure call, otherwise it is executed as a plain SQL query. Each configuration value is stripped from white characters on both ends before processing.
Please don’t use semicolon ;
at the end of the query as many JDBC drivers get confused and the query may not work.
Some queries can take arguments. Arguments are marked by question marks ?
in the query. Refer to the configuration parameters description for more details about what parameters are expected in each query.
This example shows how to use a stored procedure to add a user as a query with 2 required parameters (username, and password).
authRepository { default () { 'add-user-query' = '{call TigAddUserPlainPw(?, ?) }' } }
The same query with plain SQL parameters instead:
'add-user-query' = 'insert into users (user_id, password) values (?, ?)'
The order of the query arguments is important and must be exactly as described in specification for each parameter.
Query Name | Description | Arguments | Example Query |
---|---|---|---|
| Query executed periodically to ensure active connection with the database. | Takes no arguments. |
|
| Database initialization query which is run after the server is started. | Takes no arguments. |
|
| Query adding a new user to the database. | Takes 2 arguments: |
|
| Removes a user from the database. | Takes 1 argument: |
|
| Retrieves user password from the database for given user_id (JID). | Takes 1 argument: |
|
| Updates (changes) password for a given user_id (JID). | Takes 2 arguments: |
|
| Performs user login. Normally used when there is a special SP used for this purpose. This is an alternative way to a method requiring retrieving user password.
Therefore at least one of those queries must be defined: | Takes 2 arguments: |
|
| This query is called when user logs out or disconnects. It can record that event in the database. | Takes 1 argument: |
|
| Comma separated list of NON-SASL authentication mechanisms. Possible mechanisms are: | ||
| Comma separated list of SASL authentication mechanisms. Possible mechanisms are all mechanisms supported by Java implementation.
The most common are: |
Currently, we can only check authentication against a Drupal database at the moment. Full Drupal authentication is not implemented as of yet.
As Drupal keeps encrypted passwords in database the only possible authorization protocols are those based on PLAIN passwords.
To protect your passwords Tigase server must be used with SSL or TLS encryption.
Implementation of a Drupal database based authorization is located in tigase.db.jdbc.DrupalAuth
class. Although this class is capable of adding new users to the repository I recommend to switch in-band registration off due to the caching problems in Drupal. Changes in database are not synchronized with Drupal yet. Functionality for adding new users is implemented only to ease user accounts migration from different repository types from earlier Tigase server installations.
The purpose of that implementation was to allow all accounts administration tasks from Drupal like: account creation, all accounts settings, like e-mail, full name, password changes and so on.
Tigase server uses following fields from Drupal database: name (user account name), pass (user account password), status (status of the account). Server picks up all changes instantly. If user status is not 1 then server won’t allow user to login trough XMPP even if user provides valid password.
There is no Roster management in Drupal yet. So Roster management have to be done from the XMPP client.
Tigase XMPP Server offers support for authenticating users against an LDAP server in Bind Authentication mode.
Configuration for the LDAP support is really simple you just have to add a few lines to your config.tdsl
file.
authRepository { default () { cls = 'tigase.db.ldap.LdapAuthProvider' uri = 'ldap://ldap.tigase.com:389' 'user-dn-pattern' = 'cn=USER_ID,ou=people,dc=tigase,dc=org' } }
Please note the USER_ID
element, this is a special element of the configuration which is used to authenticate particular user. Tigase LDAP connector replaces it with appropriate data during authentication. You can control what Tigase should put into this part. In your configuration you must replace this string with one of the following:
%1$s
- use user name only for authentication (JabberID’s localpart)%2$s
- use domain name only for authentication (JabberID’s domain part)%3$s
- use the whole Jabber ID (JID) for authenticationPlease make sure that you included autoCreateUser=true
in your main data source (UserRepository and not above AuthRepository) as outlined in Important - otherwise you may run into problems with data access.
In order to enable SASL External set "Client Certificate CA" (client-trust-extension-ca-cert-path
) to the path containing Certification Authority (CA) certificate in the VHost (domain) configuration, for example /path/to/cacert.pem
File cacert.pem
contains Certificate Authority certificate which is used to sign clients certificate.
Client certificate must include user’s Jabber ID as XmppAddr
in subjectAltName
:
As specified in RFC 3920 and updated in RFC 6120, during the stream negotiation process an XMPP client can present a certificate (a “client certificate”). If a JabberID is included in a client certificate, it is encapsulated as an id-on-xmppAddr Object Identifier (“xmppAddr”), i.e., a subjectAltName entry of type otherName with an ASN.1 Object Identifier of “id-on-xmppAddr” as specified in Section 13.7.1.4 of RFC 6120, XEP-0178.
It is possible to make client certificate required using same VHost configuration and enabling option Client Certificate Required
(client-trust-extension-cert-required
).
If this option will be enabled, then client must provide certificate. This certificate will be verified against clientCertCA
. If client does not provide certificate or certificate will be invalid, TLS handshake will be interrupted and client will be disconnected.
Using this options does not force client to use SASL EXTERNAL. Client still may authenticate with other SASL mechanisms.