Skip to content

r3dlin3/phpOIDC

Repository files navigation

phpOIDC Project

About phpOIDC

Even though the code is close to the code base, it still needs to be tested for interoperability, as the base project did not provide any tests.

It provides:

  • Fully interoperable OpenID Connect Provider. It implements the following specifications :

    • OpenID Connect Core 1.0

    • OpenID Connect Discovery 1.0

    • OpenID Connect Registration 1.0

    • OpenID Connect Dynamic Registration 1.0

    • OpenID Connect Session Management 1.0

  • End-user authentication, authorization, and provides identity and basic profile information to Relying Parties

  • Web pages with themes (the default theme relies on nauvalazhar’s pages)

  • A relying provider, used for testing or demonstration

  • Docker images and docker compose ready to start (see 5 minutes quickstart)

  • Registration page to create a local account

  • Password reset page

  • Internationalization (currently English and French)

Warning
This is implementation still lacks proper administration pages.

Why start from Nomura Research Institute implementation?

There are few implementations of an OpenID Connect implementation in PHP. It provided a lot of interoperability. However, the old implementation lacked from:

  • Capability to customize the pages: HTML code was hardcoded in the PHP page

  • Lack of documentation: the documentation referred to a Debian package or few indications split among different files

  • No tests

  • Use of PEAR and composer

  • Old version of libraries

  • No Dockerfile

5 minutes quickstart

This tutorial walks you through a quick setup of phpOIDC, a MySQL instance and MailDev on Docker Compose. You need to have the latest Docker and Docker Compose version installed.

We will use the Docker Compose configuration in this repository.

To get the source code, you can:

Change into the directory with the source code and run the following command to start the needed containers:

$ docker-compose -f quickstart.yml up --build
Starting app
Starting phpoidc_mysql_1
Starting maildev
[...]

Then execute the following command:

$ docker-compose -f .\quickstart.yml exec app libs/bin/doctrine orm:schema-tool:create

You can access the homepage by going to http://localhost:8001.

Azure

It is possible to quickly deploy phpOIDC OpenID Connect Provider in Azure. Follow this doc.

Installation

There are two folders: phpOp and phpRp. They are the source code for OpenID Connect Provider and OpenID Connect Relying Party respectively.

Both can be installed on Apache or NGINX.

Dependency/Requirements

The installation of the following components is not detailed and each component must be installed beforehand:

  • Apache Web Server or NGINX. SSL is MANDATORY for production

  • MySQL (tested with MySQL 5 and 8)

  • PHP 7.2+

  • PHP Modules:

    • PDO MySQL

    • cURL

Database

Install MySQL and create a database and its user with a password.

Note
As the solution relies on Doctrine, it might work with other database but it has not already been tested.
$ sudo apt-get install mysql-server
$ mysql -p
mysql> create database `phpOidc`;
mysql> grant all on phpOidc.* to phpOidc identified by 'new_password';
mysql> quit;

The SQL script to import is provided in phpOp/create_db.sql.

Web server

Apache

To enable "Dynamic Discovery", add the following configuration to Apache’s web site configuration:

Alias /.well-known/webfinger /var/www/html/phpOp/discovery.php
Alias /.well-known/openid-configuration /var/www/html/phpOp/discovery.php
Alias /phpOp/.well-known/openid-configuration /var/www/html/phpOp/discovery.php

The path /var/www/html/ may be different depending on the location of the server’s web document root directory.

An example of the Apache configuration is provided in the folder apache

If you do not have to Apache configuration, you may use a .htaccess file with mod_rewrite

<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^.well-known/webfinger.*$ /phpOp/discovery.php$1 [NC,L]
RewriteRule ^.well-known/openid-configuration.*$ /phpOp/discovery.php$1 [NC,L]
RewriteRule ^phpOp/.well-known/openid-configuration.*$ /phpOp/discovery.php$1 [NC,L]
</IfModule>

An example of .htaccess is provided in this repository.

NGINX

To enable "Dynamic Discovery", add the following configuration to NGINX configuration (e.g. /etc/nginx/sites-enabled/default):

location ~ [^/]\.php(/|$) {
  fastcgi_split_path_info ^(.+?\.php)(/.*)$;
  if (!-f $document_root$fastcgi_script_name) {
          return 404;
  }
  fastcgi_pass app:9000;
  # With php-fpm locally:
  # fastcgi_pass unix:/var/run/php5-fpm.sock;
  fastcgi_index index.php;
  include fastcgi_params;
  fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
  fastcgi_param PATH_INFO $fastcgi_path_info;
}

location ~ /\.well-known/[webfinger|openid\-configuration] {
  alias /var/www/html/phpOp/discovery.php;
  fastcgi_split_path_info ^(.+\.php)(/.+)$;
  fastcgi_pass app:9000;
  fastcgi_index index.php;
  include fastcgi_params;
  fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
  fastcgi_param PATH_INFO $fastcgi_path_info;
}

The path /var/www/html may be different depending on the location of the server’s web document root directory.

The fastcgi_pass directive should be correctly configured for sockets or tcp.

An example of NGINX configuration is provided in this repository.

Configuration

OP

Configuration of OP is done by leveraging PHP dotenv.

Copy phpOp/.env.example as phpOp/.env and edit the file to set the configuration.

The parameters are described below:

Parameter Description Default Value

LOGFILE

Where logs are stored

app.log

LOGLEVEL

Log level. Possible values are DEBUG, INFO, NOTICE, WARNING, ERROR, CRITICAL, ALERT, EMERGENCY

DEBUG

THEME_NAME

Name of the theme

default

THEME_URI

Part of the URL for the theme. It is used to load on the client-side CSS, JavaScript, Images, etc.

relative to current script

VIEWS_PATH

Path to view files. Used by BladeOne.

${THEME_PATH}/views

ENABLE_PASSWORD_RESET

Enable password reset. Must be true or false.

true

PASSWORD_RESET_URL

Password reset URL. Can be outside current URL

computed

ENABLE_REGISTRATION

Enable registration reset. Must be true or false.

true

REGISTRATION_URL

Registration URL. Can be outside current URL

computed

ENABLE_ADMIN

Enable admin interface. Beware that current implementation of admin is insecure as there is no access control. Must be true or false.

true

ENABLE_DYNAMIC_CLIENT_REGISTRATION

Enable dynamic client registration as per defined in the specification. Must be true or false.

true

BLADE_CACHE

Path to cache. Used by BladeOne.

./cache

OP_SERVER_NAME

Specifies the OP’s server name/IP address.

ServerName of the web server, or as a fallback, based on the request.

SITE_NAME

Name of the OP (for end-user display)

${OP_SERVER_NAME}

OP_URL

Base URL of the OP (without index.php)

computed based on server and request info. For production, it is recommended to set this URL.

ENABLE_PKCE

Enable PKCE

false

OP_SIG_PKEY

path to the OP’s private key for signing

./op_sig.key

OP_SIG_PKEY_PASSPHRASE

OP’s pass phrase for the private key file

""

OP_ENC_PKEY

path to the OP’s private key for encryption

./op_enc.key

OP_ENC_PKEY_PASSPHRASE

OP’s pass phrase for the private key file

""

OP_JWK_URL

URL to OP’s public JWK

${OP_URL} . '/op.jwk'

OP_SIG_KID

OP’s Signature Kid

PHPOP-00S

OP_ENC_KID

OP’s Encryption Kid

PHPOP-00E

DB_TYPE

Type of database

mysql

DB_PORT

Port used by the database

3306

DB_DATABASE

Name of the database

phpoidc

DB_USER

User used to connect to the database

root

DB_PASSWORD

password to connect to the database

''

DB_HOST

Hostname of the database server

localhost

DB_TABLE_PREFIX

Prefix for tables

MAIL_TRANSPORT

Using mail function or smtp to send mails

mail

MAIL_HOST

Hostname of the SMTP server to send through

MAIL_PORT

Port used by SMTP.

MAIL_AUTH

Enable SMTP authentication

false

MAIL_ENCRYPTION

Enable encryption: 'ssl' , 'tls' accepted

''

MAIL_USER

User for SMTP authentication

MAIL_PASSWORD

Password for SMTP authentication

MAIL_FROM

Enable encryption: 'ssl' , 'tls' accepted

''

MAIL_REPLY_TO

Set the reply-to e-mail

MAIL_SMTP_AUTO_TLS

Boolean to enable TLS encryption automatically if a server supports it, even if SMTPSecure is not set to 'tls'.

false

FACEBOOK_CLIENT_ID

Client ID for Facebook

FACEBOOK_CLIENT_SECRET

Client secret for Facebook

FACEBOOK_REDIRECT_URL

URL use for the callback for Facebook

Computed by default based on OP_URL

GOOGLE_CLIENT_ID

Client ID for Google

GOOGLE_CLIENT_SECRET

Client secret for Google

GOOGLE_REDIRECT_URL

URL use for the callback for Google

Computed by default based on OP_URL

GITHUB_CLIENT_ID

Client ID for GitHub

GITHUB_CLIENT_SECRET

Client secret for GitHub

GITHUB_REDIRECT_URL

URL use for the callback for GitHub

Computed by default based on OP_URL

LINKEDIN_CLIENT_ID

Client ID for linkedIn

LINKEDIN_CLIENT_SECRET

Client secret for linkedIn

LINKEDIN_REDIRECT_URL

URL use for the callback for linkedIn

Computed by default based on OP_URL

RP

The relies partly on OP’s configuration and on the file phpRp/abconstants.php. Edit this file to set the parameters/

  • RP_PKEY

  • RP_PKEY_PASSPHRASE

  • RP_SIG_KID

  • RP_JWK_URL

  • RP_ENC_JWK_URL

OP and RP Signature and Encryption Keys

the OP and RP samples come with demo keys. You may want to create new 2048 bit RSA keys.

A new private key can be generated by using the following command:

openssl genrsa -out filename 2048

A JWK can be generated by using the following command:

php phpOp/makejwk.php path_to_key_filename kid ''

To renew all keys, you can execute the following command from the root folder:

  • On Windows (OpenSSL binaries for Windows can be found on their wiki):

openssl.exe genrsa -out .\phpOp\op\op_sig.key 2048
openssl.exe genrsa -out .\phpOp\op\op_enc.key 2048
php .\phpOp\makejwk.php .\phpOp\op\op_sig.key PHPOP-00S 'sig' > .\phpOp\op\op_sig.jwk
php .\phpOp\makejwk.php .\phpOp\op\op_enc.key PHPOP-00E 'enc' > .\phpOp\op\op_enc.jwk
php .\phpOp\makejwk.php mergejwks .\phpOp\op\op_sig.jwk .\phpOp\op\op_enc.jwk > .\phpOp\public\op.jwk
  • On Linux:

openssl.exe genrsa -out ./phpOp/op/op_sig.key 2048
openssl.exe genrsa -out ./phpOp/op/op_enc.key 2048
php ./phpOp/makejwk.php ./phpOp/op/op_sig.key PHPOP-00S 'sig' > ./phpOp/op/op_sig.jwk
php ./phpOp/makejwk.php ./phpOp/op/op_enc.key PHPOP-00E 'enc' > ./phpOp/op/op_enc.jwk
php ./phpOp/makejwk.php mergejwks ./phpOp/op/op_sig.jwk ./phpOp/op/op_enc.jwk > ./phpOp/public/op.jwk

Development

With Docker

As for the 5 minutes quickstart, you can run the following commands to spin off an instance

docker-compose  -f quickstart.yml up --build
docker-compose -f .\quickstart.yml exec app libs/bin/doctrine orm:schema-tool:create

In dev, the container is running a ubuntu-based image using root, so you can install anything. For instance:

$ docker-compose -f .\quickstart.yml exec app bash
# apt update && apt install vim -y

XDEBUG is activated automatically thanks to the environment variable XDEBUG_CONFIG set in the Docker Compose file.

With Visual Studio Code, add the following configuration

{
  "name": "Listen for XDebug in Docker",
  "type": "php",
  "request": "launch",
  "port": 9002,
  "pathMappings": {
    "/var/www/html": "${workspaceFolder}"
  }
}

Pages

Pages are rendered using the template engine BladeOne, a lightweight standalone implementation of Laravel’s template engine: Blade.

It is possible to clear cache if needed but running the following PowerShell script

cd phpOp
Get-ChildItem .\cache\*.bladec | Remove-Item

Tests

Acceptance tests and API tests relies on CODECEPTION. You can execute them by running the following command inside phpOp:

cd phpOp
.\libs\bin\codecept.bat run

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published