tiqr / tiqr-server-libphp
php library for tiqr authentication.
Installs: 3 439
Dependents: 1
Suggesters: 0
Security: 0
Stars: 6
Watchers: 15
Forks: 7
Open Issues: 0
Requires
- php: ^8.2
- ext-curl: *
- ext-gd: *
- ext-json: *
- ext-openssl: *
- cache/filesystem-adapter: ^1
- chillerlan/php-qrcode: ^3.4
- edamov/pushok: ^0.16.0
- google/apiclient: ^2.14
- psr/log: ^3.0
Requires (Dev)
- ext-pdo_sqlite: *
- mockery/mockery: ^1.6
- phpmd/phpmd: ^2.15
- phpunit/phpunit: ^9.6
- squizlabs/php_codesniffer: ^3.7
- dev-develop
- 4.3.1
- 4.3.0
- 4.3.0-beta1
- 4.2.0
- 4.2.0-beta2
- 4.2.0-beta1
- 4.1.0
- 4.0.1
- 4.0.0
- 3.0.2
- 3.0.1
- 3.0
- 3.0-rc2
- 3.0-rc1
- 3.0-beta5
- 3.0-beta4
- 3.0-beta3
- 3.0-beta2
- 3.0-beta1
- 2.1.0
- 2.0.0
- 1.1.13
- 1.1.12
- v1.1.11
- v1.1.10
- v1.1.7
- v1.1.6
- v1.1.5
- v1.1.4
- v1.1.3
- v1.1.2
- v1.1.1
- v1.1
- dev-main
- dev-feature/add-authenticationTimeout
- dev-master
- dev-feature/add_healthcheck
- dev-feature/php82
- dev-fix-scrutenizer-coverage
- dev-feature/upgrade-psr-log
- dev-feature/remove-mcrypt
- dev-feature/use-replace-into-for-pdo
- dev-feature/support-php8
- dev-bugfix/pdo_exception_usersecret
- dev-feature/testserver
- dev-feature/APNS2
- dev-testserver
- dev-feature/3.0
- dev-feature/universal-link
- dev-feature/remove-ocra-v1
- dev-feature/testserver-apache-php
- dev-release/2.0
- dev-feature/remove-c2dm-gcm
- dev-feature/remove-unreachable-code
- dev-maintenance/add-security-checks
- dev-update-to-php72-for-scutenizer
- dev-feature/move-expiry-period-and-make-configurable
- dev-feature/use-php-random-bytes
- dev-release/1.1
- dev-feature/state-storage-updates
- dev-feature/nfc-poc
This package is auto-updated.
Last update: 2024-11-06 11:26:52 UTC
README
A PHP library for implementing a Tiqr authentication server
The library includes a test server, see its README for details. Read the included SECURITY.md for security considerations when using this library.
Introduction
This project is a PHP implementation of a library to implement a Tiqr server. This library is not a server by itself, instead it contains functionality that help Tiqr server implementations with several tasks. You need to write the code to provide the HTTP API for the Tiqr client, and to create the web interface that the user interacts with for enrolling and authentication. This library helps with a large part of this, including:
- Handling of authentications and registration flows of the Tiqr protocol (OCRA)
- Storing of user authentication and user secret data
- Sending of push notification (Firebase Cloud Messaging, Apple Push Notifications)
- Storing of application state (for state persistency during registration and authentication workflows)
When implementing Tiqr you will need to understand the Tiqr protocol. This is documented in the Tiqr protocol documentation.
Who should use this library?
Basically anyone who wants to implement a Tiqr server for their Tiqr client Apps (Android & iOS).
History
A brief overview of notable points in time of this project
- 2010: This project was initially created in 2010
- 2012: The project was moved from a local SVN to GitHub
- 2014: The UserSecretStorage and the Ocra implementation was created
- 2015: GCM push message support was added, and several cleanup tasks where performed
- 2019: FCM push message support was added
- 2020: PHP 5 support was dropped
- 2022: Unit & integration test coverage was added, added TestServer
- 2022: 3.3: Major refactoring of UserStorage and UserSecretStorage classes, addition of PSR Logging, removal of deprecated functionality, security hardening
- 2023: 4.0: Switch to composer autoloader, add PHP 8 support, remove APNS v1 and Zend library dependency
- 2024: 4.1: Update FCM to use HTTP v1 API for google PN's, add openssl encryption type for UserSecretStorage
Ecosystem
The tiqr-server-libphp uses external libraries sparingly. It uses libraries for sending push notifications and for generating QR code images.
The rest of the library code is vanilla PHP code.
For testing purposes we use additional dev-dependencies. They include well know testing tools like PHPUnit and Mockery.
TestServer
The library includes a Tiqr TestServer that is aimed at developers and testers of tiqr clients. See the TestServer README for more information.
Future strategy
- Having a robust test coverage on the code should have a high priority on every new feature created or bug fixed.
Using the library
If you seek to implement a Tiqr server yourself, you can look at how this library is used by the Tiqr GSSP. Tiqr is an important second factor authentication method in the OpenConext Stepup ecosystem and this library is used by the Tiqr GSSP.
Another example for using this library is the Tiqr TestServer that is included with the library
The API of the tiqr-server-libphp can be found in classes starting Tiqr_
in library/tiqr/Tiqr
. Notable classes found here are:
- Tiqr_Service the main service class implementing the utility functions to handle user enrollement and authentication from a Tiqr Server.
- Factories for creating UserStorage.php and UserSecretStorage.php for different storage backends.
Security
Please read the included SECURITY.md for important security considerations when using Tiqr and using this library.
Creating the Service
An example on how to configure, create and work with the Tiqr Service
.
Config
To create the Tiqr Service you need to provide it with configuration options for the Tiqr_Service as well as the configuration for the Tiqr_StateStorage. The Tiqr_StateStorage
is used to link the API calls from the tiqr client with the API calls from your tiqr server webinterface. You must select and configure the type you want to use – (e.g. pdo) corresponds with the class (e.g. type pdo will use Tiqr_StateStorage_PDO).
The documentation of all the configuration options can be found in the Tiqr_Service class.
The APNS and FCM configuration and the Token exchange configuration is only required for sending Push Notifications to iOS and Android clients. These push notifications are an optional alternative way to start an authentication for a know user and require you to release your own app, under your own name. When not using push notifications the user must always scan a QR code.
// Options for Tiqr_Service $options = [ // General settings 'auth.protocol' => 'tiqrauth', 'enroll.protocol' => 'tiqrenroll', 'ocra.suite' => 'OCRA-1:HOTP-SHA1-6:QH10-S', 'identifier' => 'tiqr.example.com', 'name' => "TestServerController https://tiqr.example.com", 'logoUrl' => "https://tiqr.example.com/logoUrl", 'infoUrl' => "https://tiqr.example.com/infoUrl", // APNS configuration, required for sending push notifications to iOS devices 'apns.certificate' => 'files/apns.pem', 'apns.environment' => 'production', //FCM configuration, required for sending push notifications to Android devices 'firebase.projectId' => '12345-abcde', 'firebase.credentialsFile' => 'google.json', // Session storage 'statestorage' => [ 'type' => 'pdo', 'dsn' => 'mysql:host=localhost;dbname=state_store' 'username' => 'state_rw' 'password' => 'secret' 'cleanup_probability' => 0.75 ], // Token exchange configuration (deprecated) 'devicestorage' => [ 'type' => 'tokenexchange', 'url' => 'tx://tiqr.example.com', 'appid' => 'app_id', ], ]
See this instructions for generating the firebase.projectId
and firebase.credentialsFile
Autoloading and composer
Add the library to your project using composer. I.e.:
$ composer require tiqr/tiqr-server-libphp
and include the vendor/autoload.php
generated by composer:
<?php # Include the composer autoloader require_once 'vendor/autoload.php';
Creation
Creating the Tiqr_Service
is now as simple as creating a new instance with the configuration
# Create the Tiqr_Service $service = new Tiqr_Service($options)
Example Usage
The service has 22 public methods that are used to enroll a new user, but also to run authentications. The purpose of this section is not to be an API documentation. But an example is shown on how the service methods behave.
For more comprehensible examples on how to work with the Tiqr library, have a look at the Tiqr TestServer implementation. It can be found here. Or have a look at a real world implementation on our Stepup-tiqr project. A good entrypoint is the TiqrServer and the TiqrFactory.
Logging
We put a lot of effort adding relevant logging to the library. Logging adheres to the PSR-3 logging standard. Services, Repositories and other helper classes in the library are configured with a LoggerInterface instance when they are instantiated. Your application should have a logging solution that can fit into that. Otherwise, we suggest looking at Monolog as a logging solution that is very flexible, and adheres to the PSR-3 standard.
In practice, when creating the Tiqr_Service, you need to inject your Logger in the constructor. The factory classes also ask for a logger instance, for example: when creating a user secret storage.
An example using Monolog (your framework will allow you to DI the logger into your own tiqr service implementation):
use Monolog\Logger; use Monolog\Handler\StreamHandler; // Create a log channel that logs alle messages of level DEBUG and above to a file $logger = new Logger('name'); $logger->pushHandler(new StreamHandler('path/to/your.log', Logger::DEBUG)); $this->tiqrService = new Tiqr_Service($logger, $options);
UserStorage and UserSecretStorage
The UserStorage.php and UserSecretStorage.php are used to store Tiqr user account data (UserStorage) and to store the user's OCRA secret (UserSecretStorage). The use of both classes is optional as you provide Tiqr_Service() with the userid and secret, these can come from anywhere. The 'file' type is more suitable for testing and development. The 'pdo' type is intended for production use.
The UserSecretStorage supports encrypting the user secret using e.g. an AES key. You can also provide your own encrpytion implementation. See UserSecretStorage.php for more information.
Example UserStorage and UserSecretStorage usage
Example using a single mysql 'user' table for user and user secret storage, the user's secret is stored encrypted using an AES key.
Create a user storage table in MySQL
CREATE TABLE IF NOT EXISTS user ( id integer NOT NULL PRIMARY KEY AUTO_INCREMENT, userid varchar(30) NOT NULL UNIQUE, displayname varchar(30) NOT NULL, secret varchar(128), loginattempts integer, tmpblocktimestamp BIGINT, tmpblockattempts integer, blocked tinyint(1), notificationtype varchar(10), notificationaddress varchar(64) );
Create and configure the UserStorage and UserSecretStorage classes
$user_storage = Tiqr_UserStorage::getUserStorage( 'pdo', $logger, array( 'dsn' => 'mysql:host=mysql.example.com;dbname=tiqr', 'username' => 'tiqr_rw', 'password' => 'secret', 'table' => 'user' ) ); $secret_storage = Tiqr_UserSecretStorage::getSecretStorage( 'pdo', $logger, array( 'dsn' => 'mysql:host=mysql.example.com;dbname=tiqr', 'username' => 'tiqr_rw', 'password' => 'secret', 'table' => 'user', // Encrypt the secret using an AES key 'encryption' => [ 'type' => 'openssl', 'cipher' => 'aes-256-cbc', // Cypher to use for encryption 'key_id' => 'key_2024', // ID of the key to use for encryption 'keys' => [ 'key_2024' => '0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20', // Key used for encryption 'key_2015' => '303132333435363738393a3b3c3d3e3f303132333435363738393a3b3c3d3e3f', // A (old) key that can be used for decryption ], ], ) ); $user_storage->createUser('jdoe', 'John Doe'); // Create user with id 'jdoe' and displayname 'John Doe'. 'jdoe' is the user's unique identifier. $secret_storage->setSecret('jdoe', '4B7AD80B70FC758C99EFDD7E93932EEE43B9378A1AE5E26098B912C2ECA91828'); // Set the user's secret // Set some other data that is associated with the user $user_storage->setNotificationType('jdoe', 'APNS'); $user_storage->setNotificationAddress('jdoe', '251afb4304140542c15252e4a07c4211b441ece5');
Running tests
A growing set of unit tests can and should be used when developing the tiqr-server-libphp project.
To run all te QA tests:
composer install
composer test
After composer install
, you can run the individual tests from the /qa/ci/
directory. E.g. to run phpunit tests only:
./ci/qa/phpunit