From 011cd1dc78baff423eb7f72309eb5d0384db2e7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Ivan=C4=8Di=C4=87?= Date: Wed, 8 Oct 2025 16:33:37 +0200 Subject: [PATCH 1/8] Start with dedicated docs --- docs/installation.md | 1 + docs/oidc.md | 13 +++++++++++++ 2 files changed, 14 insertions(+) create mode 100644 docs/installation.md create mode 100644 docs/oidc.md diff --git a/docs/installation.md b/docs/installation.md new file mode 100644 index 00000000..3aaa5d38 --- /dev/null +++ b/docs/installation.md @@ -0,0 +1 @@ +# Installation diff --git a/docs/oidc.md b/docs/oidc.md new file mode 100644 index 00000000..856dc278 --- /dev/null +++ b/docs/oidc.md @@ -0,0 +1,13 @@ +# OIDC Module + +OIDC module adds support for the OpenID Provider role from the OpenID Connect protocol +through a SimpleSAMLphp module installable via Composer. It is based on +[OAuth2 Server from the PHP League](https://oauth2.thephpleague.com/). + +Currently supported flows are: +* Authorization Code flow, with PKCE support (response_type 'code') +* Implicit flow (response_type 'id_token token' or 'id_token') +* Refresh Token flow + +# TOC +* [Installation](installation.md) From e25443f0a7522532b05aeaf4e7aba80544f1950d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Ivan=C4=8Di=C4=87?= Date: Wed, 8 Oct 2025 16:37:56 +0200 Subject: [PATCH 2/8] Add .markdownlintignore --- .markdownlintignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .markdownlintignore diff --git a/.markdownlintignore b/.markdownlintignore new file mode 100644 index 00000000..208a5991 --- /dev/null +++ b/.markdownlintignore @@ -0,0 +1 @@ +vendor/* \ No newline at end of file From b1f13397ec6c4b2d1ce55bd80bc669f3d3bfbf6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Ivan=C4=8Di=C4=87?= Date: Thu, 9 Oct 2025 13:43:49 +0200 Subject: [PATCH 3/8] Set initial docs structure --- docs/configuration.md | 220 ++++++++++++++++++++++++++++++++++++++ docs/conformance.md | 104 ++++++++++++++++++ docs/docker.md | 135 ++++++++++++++++++++++++ docs/faq.md | 20 ++++ docs/installation.md | 110 +++++++++++++++++++ docs/oidc.md | 61 +++++++++-- docs/upgrade.md | 240 ++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 882 insertions(+), 8 deletions(-) create mode 100644 docs/configuration.md create mode 100644 docs/conformance.md create mode 100644 docs/docker.md create mode 100644 docs/faq.md create mode 100644 docs/upgrade.md diff --git a/docs/configuration.md b/docs/configuration.md new file mode 100644 index 00000000..3dc13821 --- /dev/null +++ b/docs/configuration.md @@ -0,0 +1,220 @@ +# Configuration + +This guide summarizes key configuration topics for the OIDC module. +It complements the inline comments in `config/module_oidc.php`. + +- Caching protocol artifacts +- Relying Party (RP) administration UI +- Cron integration +- Endpoint locations and well-known URLs +- Key rollover +- Apache Authorization header note +- Private scopes +- Attribute translation +- Auth Proc filters (OIDC) +- Client registration permissions + +## Caching protocol artifacts + +The configured database is the primary storage for protocol artifacts: +access tokens, authorization codes, refresh tokens, clients, and user +records. In production, you should also configure a cache in front of the +DB to improve performance during traffic spikes. + +Caching uses Symfony Cache, so any compatible adapter can be used. See the +`module_oidc.php` configuration file for adapter selection and parameters. + +## Relying Party (RP) administration + +The module provides a UI to manage clients (create, read, update, delete). +After you create the database schema, go to the SimpleSAMLphp admin area: + +- OIDC > Client Registry + +Notes: +- Clients can be public or confidential. +- Public clients using Authorization Code flow must send PKCE parameters. +- Client ID and secret are generated; use the "show" button to reveal. + +## Cron integration + +Enable and configure the SimpleSAMLphp cron module to purge expired tokens: + +- https://simplesamlphp.org/docs/stable/cron/cron.html + +## Endpoint locations and well-known URLs + +After deployment, visit the SimpleSAMLphp admin area: + +- OIDC > Protocol / Federation Settings + +There you can see discovery URLs. Typical discovery endpoints are: + +- OpenID Connect Discovery: + https://yourserver/simplesaml/module.php/oidc/.well-known/openid-configuration +- OpenID Federation configuration: + https://yourserver/simplesaml/module.php/oidc/.well-known/openid-federation + +You may publish these as ".well-known" URLs at the web root using your +web server. For example, for `openid-configuration`: + +nginx: + +```nginx +location = /.well-known/openid-configuration { + rewrite ^(.*)$ /simplesaml/module.php/oidc/.well-known/openid-configuration break; + proxy_pass https://localhost; +} +``` + +Apache: + +```apache +RewriteEngine On +RewriteRule ^/.well-known/openid-configuration(.*) \ + /simplesaml/module.php/oidc/.well-known/openid-configuration$1 [PT] +``` + +## Key rollover + +You can configure an additional key pair to publish via JWKS endpoints or +properties. This lets RPs pre-fetch the new public key before you switch +signing to the new private key. Once RPs have cached the new JWKS, you can +perform the key switch. + +## Apache Authorization header note + +Apache may strip the `Authorization` header (Bearer) from requests, a known +issue: https://github.com/symfony/symfony/issues/19693 + +Although the module includes a fallback, it has performance implications. +Configure Apache to preserve the header using one of these snippets: + +```apache +RewriteEngine On +RewriteCond %{HTTP:Authorization} .+ +RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] +``` + +or + +```apache +SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1 +``` + +If not set, you will see warnings about this in the logs. + +## Private scopes + +The module supports the standard scopes: `openid`, `email`, `address`, +`phone`, and `profile`. You can add private scopes in `module_oidc.php`: + +```php + [ + 'private' => [ + 'description' => 'private scope', + 'claim_name_prefix' => '', + 'are_multiple_claim_values_allowed' => false, + 'attributes' => ['national_document_id'], + ], + ], +]; +``` + +## Attribute translation + +Default SAML-to-OIDC claim mapping follows the REFEDS guidance: +https://wiki.refeds.org/display/GROUPS/Mapping+SAML+attributes+to+OIDC+Claims + +You can change or extend this mapping in `module_oidc.php`. Example: + +```php + [ + // Overwrite default mapping + 'sub' => [ + 'uid', + 'eduPersonPrincipalName', + 'eduPersonTargetedID', + 'eduPersonUniqueId', + ], + // Remove default mapping by setting an empty array + 'family_name' => [], + + // New claim created from SAML attribute + 'national_document_id' => [ + 'schacPersonalUniqueId', + ], + ], +]; +``` + +## Auth Proc filters (OIDC) + +Standard SAML Auth Proc Filters do not run during OIDC authN because not +all SAML entities are present (like a Service Provider). Instead, use the +`authproc.oidc` configuration option to define filters specific to OIDC. + +The OIDC authN state does not include all keys present in SAML authN. +Available SAML-like keys include: + +- ['Attributes'] +- ['Authority'] +- ['AuthnInstant'] +- ['Expire'] + +Source and Destination entity IDs correspond to OP issuer and Client ID: + +- ['Source']['entityid'] → OP issuer ID +- ['Destination']['entityid'] → RP (client) ID + +Additional OIDC data in the state: + +- ['Oidc']['OpenIdProviderMetadata'] +- ['Oidc']['RelyingPartyMetadata'] +- ['Oidc']['AuthorizationRequestParameters'] + +Example filter configuration: + +```php + [ + 50 => [ + 'class' => 'core:AttributeAdd', + 'groups' => ['users', 'members'], + ], + ], +]; +``` + +## Client registration permissions + +You can allow users to register their own clients. Control this via the +`permissions` setting in `module_oidc.php`. + +Permissions expose functionality to specific users. In the following +example, a user's `eduPersonEntitlement` is examined. To perform an action +requiring the `client` permission (register/edit/delete a client) the user +needs one of the listed entitlements. + +```php + [ + 'attribute' => 'eduPersonEntitlement', + 'client' => ['urn:example:oidc:manage:client'], + ], +]; +``` + +Users can visit the following link for administration: + +- https://example.com/simplesaml/module.php/oidc/clients/ diff --git a/docs/conformance.md b/docs/conformance.md new file mode 100644 index 00000000..c7d2708a --- /dev/null +++ b/docs/conformance.md @@ -0,0 +1,104 @@ +# OpenID Conformance + +This guide summarizes how to run the OpenID Foundation conformance tests +against this module, both locally and using the hosted service. + +- Run conformance tests locally +- Run hosted tests + +## Run conformance tests locally + +This approach is best when you want to test changes without deploying. + +### Run conformance images + +Clone, build, and run the conformance test suite: + +```bash +git clone https://gitlab.com/openid/conformance-suite.git +cd conformance-suite +git checkout release-v5.1.35 +MAVEN_CACHE=./m2 docker-compose -f builder-compose.yml run builder +docker-compose up +``` + +This starts the Java conformance app and a MongoDB server. Then: + +- Visit https://localhost:8443/ +- Create a new plan: + "OpenID Connect Core: Basic Certification Profile Authorization server test" +- Click the JSON tab and paste + `conformance-tests/conformance-basic-local.json` from this repo. + +Next, run your SSP OIDC image. + +### Run SSP + +Run SSP with OIDC on the same Docker network as the conformance tests so +containers can communicate. See the "Docker Compose" section in the +README for details. + +### Run conformance tests (interactive) + +The tests are interactive and will ask you to authenticate. Some tests +require clearing cookies to confirm a scenario; others require existing +session cookies. You may be redirected to +`https://localhost.emobix.co.uk:8443/` (the Java app). Accept SSL +warnings as needed. + +### Run automated tests + +Once manual tests pass, you can automate the browser portion: +https://gitlab.com/openid/conformance-suite/-/wikis/Design/BrowserControl + +From the `simplesamlphp-module-oidc` directory: + +```bash +# Adjust to your conformance-suite installation path +OIDC_MODULE_FOLDER=. + +# Basic profile +conformance-suite/scripts/run-test-plan.py \ + --expected-failures-file ${OIDC_MODULE_FOLDER}/conformance-tests/basic-warnings.json \ + --expected-skips-file ${OIDC_MODULE_FOLDER}/conformance-tests/basic-skips.json \ + "oidcc-basic-certification-test-plan[server_metadata=discovery][client_registration=static_client]" \ + ${OIDC_MODULE_FOLDER}/conformance-tests/conformance-basic-ci.json + +# Implicit profile +conformance-suite/scripts/run-test-plan.py \ + --expected-failures-file ${OIDC_MODULE_FOLDER}/conformance-tests/implicit-warnings.json \ + --expected-skips-file ${OIDC_MODULE_FOLDER}/conformance-tests/implicit-skips.json \ + "oidcc-implicit-certification-test-plan[server_metadata=discovery][client_registration=static_client]" \ + ${OIDC_MODULE_FOLDER}/conformance-tests/conformance-implicit-ci.json + +# RP initiated back-channel logout +conformance-suite/scripts/run-test-plan.py \ + "oidcc-backchannel-rp-initiated-logout-certification-test-plan[response_type=code][client_registration=static_client]" \ + ${OIDC_MODULE_FOLDER}/conformance-tests/conformance-back-channel-logout-ci.json + +# RP initiated logout +conformance-suite/scripts/run-test-plan.py \ + "oidcc-rp-initiated-logout-certification-test-plan[response_type=code][client_registration=static_client]" \ + ${OIDC_MODULE_FOLDER}/conformance-tests/conformance-rp-initiated-logout-ci.json +``` + +Prerequisites: run the docker deploy image for conformance tests (see +README) and the conformance test image first. + +## Run hosted tests + +The OpenID Foundation hosts the conformance testing software. Your OIDC +OP must be publicly accessible on the internet. + +### Deploy SSP OIDC image + +Use the docker image described in the README. It contains a SQLite DB +pre-populated with data for the tests. Build and run the image. + +### Register and create conformance tests + +Visit https://openid.net/certification/instructions/ + +Use the `json` configs under `conformance-tests` to configure your cloud +instances. Update `discoveryUrl` to the deployed location. Adjust `alias` +if it conflicts with existing test suites (it is used in redirect URIs). diff --git a/docs/docker.md b/docs/docker.md new file mode 100644 index 00000000..0d7e1aac --- /dev/null +++ b/docs/docker.md @@ -0,0 +1,135 @@ +# Using Docker + +This document shows how to run and test the module with Docker. + +- Run with the current git branch (live mount) +- Local testing with other DBs +- Testing AuthProc filters +- Build image for conformance tests +- Docker Compose + +## Run with the current git branch (live mount) + +Run an SSP image with the current OIDC module mounted read-only. Changes +in your checkout are reflected live in the container. + +```bash +docker run --name ssp-oidc-dev \ + --mount type=bind,source="$(pwd)",target=/var/simplesamlphp/staging-modules/oidc,readonly \ + -e STAGINGCOMPOSERREPOS=oidc \ + -e COMPOSER_REQUIRE="simplesamlphp/simplesamlphp-module-oidc:@dev" \ + -e SSP_ADMIN_PASSWORD=secret1 \ + --mount type=bind,source="$(pwd)/docker/ssp/module_oidc.php",target=/var/simplesamlphp/config/module_oidc.php,readonly \ + --mount type=bind,source="$(pwd)/docker/ssp/authsources.php",target=/var/simplesamlphp/config/authsources.php,readonly \ + --mount type=bind,source="$(pwd)/docker/ssp/config-override.php",target=/var/simplesamlphp/config/config-override.php,readonly \ + --mount type=bind,source="$(pwd)/docker/ssp/oidc_module.crt",target=/var/simplesamlphp/cert/oidc_module.crt,readonly \ + --mount type=bind,source="$(pwd)/docker/ssp/oidc_module.key",target=/var/simplesamlphp/cert/oidc_module.key,readonly \ + --mount type=bind,source="$(pwd)/docker/apache-override.cf",target=/etc/apache2/sites-enabled/ssp-override.cf,readonly \ + -p 443:443 cirrusid/simplesamlphp:v2.3.5 +``` + +Then visit: + +- https://localhost/simplesaml/ + +The OIDC configuration endpoint is available at: + +- https://localhost/.well-known/openid-configuration + +## Local testing with other DBs + +You can test it against another database such as PostgreSQL. + +1) Create a Docker network: + +```bash +docker network create ssp-oidc-test +``` + +2) Run a DB container: + +```bash +docker run --name oidc-db \ + --network ssp-oidc-test \ + -e POSTGRES_PASSWORD=oidcpass \ + -p 25432:5432 \ + -d postgres:15 +``` + +3) Run SSP (from the prior command) with these additions: + +```bash +-e DB.DSN="pgsql:host=oidc-db;dbname=postgres" \ +-e DB.USERNAME="postgres" \ +-e DB.PASSWORD="oidcpass" \ +--network ssp-oidc-test \ +``` + +## Testing AuthProc filters + +Enable the example AuthProc filters in `module_oidc.php` that set +`firstname` and `sn` and configure the preprod warning filter. This shows +that an authproc can redirect and processing resumes. + +When running Docker, adjust `COMPOSER_REQUIRE` to include the module: + +```text +-e "COMPOSER_REQUIRE=simplesamlphp/simplesamlphp-module-oidc:@dev \ + simplesamlphp/simplesamlphp-module-preprodwarning" +``` + +You can register a client from https://oidcdebugger.com/ to test. + +## Build image for conformance tests + +Build an image that contains a pre-configured sqlite database. + +```bash +GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD) +IMAGE_TAG=$(tr '/' '_' <<< "$GIT_BRANCH") + +docker build -t "simplesamlphp/simplesamlphp-oidc:dev-$IMAGE_TAG" \ + --build-arg OIDC_VERSION=dev-${GIT_BRANCH} \ + -f docker/Dockerfile . + +docker run --name ssp-oidc-dev-image \ + -e SSP_ADMIN_PASSWORD=secret1 \ + -p 443:443 simplesamlphp/simplesamlphp-oidc:dev-$IMAGE_TAG +``` + +Publish the image where you can retrieve it. Example: + +```bash +docker tag "simplesamlphp/simplesamlphp-oidc:dev-$IMAGE_TAG" \ + "cirrusid/simplesamlphp-oidc:dev-$IMAGE_TAG" + +docker push "cirrusid/simplesamlphp-oidc:dev-$IMAGE_TAG" +``` + +The DB is not on a shared volume. Changes are lost if the container +restarts. Backup example: + +```bash +docker exec ssp-oidc-dev-image sqlite3 /var/simplesamlphp/data/mydb.sq3 '.dump' \ + > docker/conformance.sql +``` + +Conformance tests are easier to run locally. See [Conformance](conformance.md). + +## Docker Compose + +Docker Compose runs multiple containers to ease testing. It builds an +image containing the OIDC module. You can remove `--build` to reuse an +existing container. + +```bash +# Use current branch/git checkout. Composer installs local checkout +OIDC_VERSION=@dev docker-compose -f docker/docker-compose.yml --project-directory . up --build + +# Use a specific module version +OIDC_VERSION=dev-master docker-compose -f docker/docker-compose.yml --project-directory . up --build +``` + +Visit the OP and verify a few clients exist: + +- https://op.local.stack-dev.cirrusidentity.com/simplesaml/ diff --git a/docs/faq.md b/docs/faq.md new file mode 100644 index 00000000..5766dadc --- /dev/null +++ b/docs/faq.md @@ -0,0 +1,20 @@ +# FAQ + +A few common questions gathered from prior discussions. + +## Set JSON type for claims + +You can set the type of claim by prefixing the claim name with `int:`, +`bool:` or `string:`. If no prefix is present, `string` is assumed. + +If a custom claim name starts with a prefix (example: `int:mycustomclaim`) +you can add one of the type prefixes (example: `string:int:mycustomclaim`) +to force the module to release a claim with the original prefix in it +(example: claim `int:mycustomclaim` of type `string`). + +## Release photo + +The OIDC `picture` claim is a URL, while the LDAP attribute `jpegPhoto` +is often a base64 string. To use `jpegPhoto`, try an authproc filter to +turn it into a data URL by adding the `data:image/jpeg;base64,` prefix. +Support for data URLs varies by OIDC client, so test your clients. diff --git a/docs/installation.md b/docs/installation.md index 3aaa5d38..50131b77 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -1 +1,111 @@ # Installation + +This guide walks you through installing, enabling, and preparing the OIDC +module in SimpleSAMLphp. + +## 1. Install the module + +Run: + +```bash +composer require simplesamlphp/simplesamlphp-module-oidc +``` + +## 2. Configure the module + +Copy the configuration template into your SimpleSAMLphp config directory +and review all options: + +```bash +cp modules/oidc/config/module_oidc.php.dist config/module_oidc.php +``` + +## 3. Configure the database + +The module uses SimpleSAMLphp's database feature to store access and +refresh tokens, user data, and other artifacts. Edit `config/config.php` +and ensure at least the following parameters are set: + +```php +'database.dsn' => 'mysql:host=server;dbname=simplesamlphp;charset=utf8', +'database.username' => 'user', +'database.password' => 'password', +``` + +Note: SQLite, PostgreSQL, and MySQL are supported. + +## 4. Create RSA key pairs + +ID and Access tokens are signed JWTs. Create a public/private RSA key +pair for OIDC protocol operations. If you plan to use OpenID Federation, +create a separate key pair for federation operations. + +Generate private keys without a passphrase: + +```bash +openssl genrsa -out cert/oidc_module.key 3072 +openssl genrsa -out cert/oidc_module_federation.key 3072 +``` + +Generate private keys with a passphrase: + +```bash +openssl genrsa -passout pass:myPassPhrase -out cert/oidc_module.key 3072 +openssl genrsa -passout pass:myPassPhrase -out cert/oidc_module_federation.key 3072 +``` + +Extract public keys: + +Without passphrase: + +```bash +openssl rsa -in cert/oidc_module.key -pubout -out cert/oidc_module.crt +openssl rsa -in cert/oidc_module_federation.key -pubout -out cert/oidc_module_federation.crt +``` + +With a passphrase: + +```bash +openssl rsa -in cert/oidc_module.key -passin pass:myPassPhrase -pubout -out cert/oidc_module.crt +openssl rsa -in cert/oidc_module_federation.key -passin pass:myPassPhrase -pubout -out cert/oidc_module_federation.crt +``` + +If you use different file names or a passphrase, update +`config/module_oidc.php` accordingly. + +## 5. Enable the module + +Edit `config/config.php` and enable `oidc`: + +```php +'module.enable' => [ + 'exampleauth' => false, + 'core' => true, + 'admin' => true, + 'saml' => true, + // enable oidc module + 'oidc' => true, +], +``` + +## 6. Run database migrations + +Run the built-in migrations to create required tables. + +Option A: Web UI + +- Go to the admin area, then `OIDC` > `Database Migrations` and click the + available button. + +Option B: Command line + +```bash +php modules/oidc/bin/install.php +``` + +## 7. Next steps + +- Configure caches, endpoints, and other options: + see [Configuration](configuration.md) +- Administer clients from the UI: + see [Relying Party (RP) Administration](configuration.md#relying-party-rp-administration) diff --git a/docs/oidc.md b/docs/oidc.md index 856dc278..2111d1f0 100644 --- a/docs/oidc.md +++ b/docs/oidc.md @@ -1,13 +1,58 @@ # OIDC Module -OIDC module adds support for the OpenID Provider role from the OpenID Connect protocol -through a SimpleSAMLphp module installable via Composer. It is based on +This module adds support for the OpenID Provider (OP) role from the +OpenID Connect protocol to SimpleSAMLphp. It is installable via Composer +and is based on the [OAuth2 Server from the PHP League](https://oauth2.thephpleague.com/). -Currently supported flows are: -* Authorization Code flow, with PKCE support (response_type 'code') -* Implicit flow (response_type 'id_token token' or 'id_token') -* Refresh Token flow +Supported flows: +- Authorization Code, with PKCE (response_type: `code`) +- Implicit (response_type: `id_token token` or `id_token`) +- Refresh Token -# TOC -* [Installation](installation.md) +![Main screen capture](oidc.png) + +## Note on OpenID Federation (OIDFed) + +OpenID Federation support is in draft, as is the +[specification](https://openid.net/specs/openid-federation-1_0). You can +expect breaking changes in future releases related to OIDFed +capabilities. OIDFed can be enabled or disabled in the module +configuration. + +Currently supported OIDFed features: +- Automatic client registration using a Request Object (by value) +- Federation participation limiting based on Trust Marks +- Endpoint for issuing a configuration entity statement (about itself) +- Fetch endpoint for issuing statements about subordinates (clients) +- Subordinate listing endpoint + +OIDFed is implemented using the +[SimpleSAMLphp OpenID library](https://github.com/simplesamlphp/openid). + +## Version compatibility + +Minor versions listed show which SimpleSAMLphp versions were used during +module development. SimpleSAMLphp follows semantic versioning for its +API since v2.0. For example, v5.* of the OIDC module should work with +any v2.* of SimpleSAMLphp. PHP version requirements may differ. + +- OIDC v6.* → SimpleSAMLphp v2.3.*, v2.4.* → PHP >= 8.2 (recommended) +- OIDC v5.* → SimpleSAMLphp v2.1.* → PHP >= 8.1 +- OIDC v4.* → SimpleSAMLphp v2.0.* → PHP >= 8.0 +- OIDC v3.* → SimpleSAMLphp v2.0.* → PHP >= 7.4 +- OIDC v2.* → SimpleSAMLphp v1.19.* → PHP >= 7.4 + +Upgrading? See the [upgrade guide](upgrade.md). + +## Documentation + +- Getting started: [Installation](installation.md) +- Configure and operate: [Configuration](configuration.md) +- Manage clients and UI: see [Configuration](configuration.md#relying-party-rp-administration) +- Endpoints and discovery: see + [Configuration](configuration.md#endpoint-locations-and-well-known-urls) +- Running with containers: [Using Docker](docker.md) +- Conformance tests: [OpenID Conformance](conformance.md) +- Upgrading between versions: [Upgrade guide](upgrade.md) +- Common questions: [FAQ](faq.md) diff --git a/docs/upgrade.md b/docs/upgrade.md new file mode 100644 index 00000000..1475f6b5 --- /dev/null +++ b/docs/upgrade.md @@ -0,0 +1,240 @@ +# Upgrade guide + +This is an upgrade guide from versions 1 → 6. Review the changes and +apply those relevant to your deployment. + +## Version 5 to 6 + +New features: +- Caching support for OIDC protocol artifacts like Access Tokens, +Authorization Codes, Refresh Tokens, but also client and user data. +The cache layer stands in front of the database store, so it can +improve performance, especially in cases of a sudden surge of +users trying to authenticate. Implementation is based on a Symfony +Cache component, so any compatible Symfony cache adapter can be used. +Check the module config file for more information on how to set the +protocol cache. +- Key rollover support - you can now define an additional (new) +private / public key pair which will be published on the relevant +JWKS endpoint or contained in JWKS property. In this way, you can +"announce" a new public key which can then be fetched by RPs, +and do the switch between "old" and "new" key pair when you +find appropriate. +- OpenID Federation capabilities: + - Automatic client registration using a Request Object (passing it by value) + - Federation participation limiting based on Trust Marks + - Endpoint for issuing a configuration entity statement + (statement about itself) + - Fetch endpoint for issuing statements about subordinates + (registered clients) + - (from v6.1) Subordinate listing endpoint + - Clients can now be configured with new properties: + - Entity Identifier + - Supported OpenID Federation Registration Types + - Federation JWKS + - Protocol JWKS, JWKS URI and Signed JWKS URI, + - Registration type (manual, federated_automatic, or other in the future) + - Is Federated flag (indicates participation in federation context) + - Timestamps: created_at, updated_at, expires_at +- Improved AuthProc filter support + - Support authproc filters that need to redirect and later resume processing + - `consent` and `preprodwarning` are two authprocs that redirect for + user interaction and are now supported + - Uses SSP's ProcessingChain class for closer alignment with SAML IdP + configuration. + - Allows additional configuration of authprocs in the main + `config.php` under key `authproc.oidc` +- Authorization endpoint now also supports sending request parameters using +HTTP POST method, in addition to GET. +- Added support for passing authorization request parameters as JWTs, +specifically - passing a Request Object by Value: + https://openid.net/specs/openid-connect-core-1_0.html#RequestObject +- Added support for `private_key_jwt` client authentication method at +token endpoint: + https://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication + +New configuration options: + +- (from v6.1) Show `claims_supported` claim in OP Discovery endpoint - +you can now choose to show supported claims, as is recommended by OpenID +Connect Discovery specification +https://openid.net/specs/openid-connect-discovery-1_0.html. +- (optional) Issuer - you can now override the issuer (OP identifier). +If not set, it falls back to the current scheme, host, and optionally +a port (as in all previous module versions). +- (optional) Protocol caching adapter and its arguments +- (optional) OpenID Federation-related options (needed if federation +capabilities are to be used): + - enabled or disabled federation capabilities + - valid trust anchors + - authority hints + - federation caching adapter and its arguments + - PKI keys - federation keys used, for example, to sign federation entity + statements + - federation participation limiting based on Trust Marks for RPs + - (from v6.1) own Trust Marks to dynamically fetch + - signer algorithm + - entity statement duration + - organization name + - display name + - description + - keywords + - contacts + - logo URI + - policy URI + - information URI + - homepage URI (renamed to organization_uri in draft-43) + - organization URI + +Major impact changes: + +- PHP version requirement was bumped to v8.2 + +Medium impact changes: + +- Database schema has been updated, so you'll have to run the DB migrations +as described in the README file. +- OIDC protocol endpoints ('authorization_endpoint', 'token_endpoint', +'userinfo_endpoint', 'end_session_endpoint', 'jwks_uri') are now available as +new routes which use Symfony routing and container mechanism. This was done as +an effort to move to the default SimpleSAMLphp way of working with routes and +services. New routes are now published by default in "OP Configuration" +endpoint, which is now also available as +`/module.php/oidc/.well-known/openid-configuration`. If you are +publishing that URL as a "well-known" URL ('/.well-known/openid-configuration'), +make sure to update your web server configuration to reflect that change +(you can refer to README for examples). All old routes (routes served by +PHP files in the public folder) will stay available in this version, +which should allow all RPs to update OP configuration in time. +Old routes will be removed in version 7. +- If you are using Apache web server: you should check the README file which +now contains a note on how to configure Apache to preserve Authorization +HTTP headers with a Bearer token scheme (stripping of this header in Apache is a +known 'issue': https://github.com/symfony/symfony/issues/19693). If you don't +set this config, you'll now get warnings about this situation in your logs. +The new authproc filter processing will look in an additional location for +filters, in the main `config.php` under key `authproc.oidc` +- Removed support for plain OAuth2 Implicit flow (response_type `token`), +because of very low usage. Note that the OIDC Implicit flow is still supported +(response_type `id_token token` or `id_token`). + +Low-impact changes + +- In an effort to move to SimpleSAMLphp way of working with user interface (UI), +the client management UI was updatedto extend from the SimpleSAMLphp base +template. In addition, we have also introduced some configuration overview +pages where you can take a quick view of some of the configuration values for +the module. OIDC related pages are now available from the main SimpleSAMLphp +menu in the Administration area. +- The OIDC config template file has been moved from +`config-templates/module_oidc.php` to `config/module_oidc.php.dist`. +This is only relevant for new installations, since initially it is necessary +to copy the template file to the default SSP config dir. + +Below are also some internal changes that should not have an impact on the +OIDC OP implementors. However, if you are using this module as a library or +extending from it, you will probably encounter breaking changes, since a lot +of code has been refactored: + +- Upgraded to v5 of lcobucci/jwt https://github.com/lcobucci/jwt +- Upgraded to v3 of laminas/laminas-diactoros +https://github.com/laminas/laminas-diactoros +- SimpleSAMLphp version used during development was bumped to v2.3 +- In Authorization Code Flow, a new validation was added which checks for +'openid' value in the 'scope' parameter. Up to now, the 'openid' value was +dynamically added if not present. In Implicit Code Flow this validation was +already present. +- Removed importer from the legacy OAuth2 module, as it is very unlikely that +someone will upgrade from the legacy OAuth2 module to v6 of oidc module. +If needed, one can upgrade to earlier versions of the `oidc` module, and then +to v6. + +# Version 4 to 5 + +Major impact changes: + +- PHP version requirement was bumped to v8.1 + +Medium impact changes: + +- Module config options in the file 'module_oidc.php' are now using constants +for config keys. The values for constants are taken from the previous version +of the module, so theoretically you don't have to rewrite your current config +file, although it is recommended to do so. + +Low-impact changes: + +- Removed the 'kid' config option which was not used in the codebase +(from v2 of the module, the 'kid' value is the fingerprint of the certificate). + +Below are some internal changes that should not have an impact on the OIDC OP +implementors. However, if you are using this module as a library or extending +from it, you will probably encounter breaking changes, since a lot of code +has been refactored: + +- psalm error level set to 1, which needed a fair number of code adjustments +- refactored to strict typing whenever possible (psalm can now infer +types for >99% of the codebase) +- refactored to PHP v8.* (up to PHP v8.1) code styling whenever possible, +like using constructor property promotion, match expressions... +- removed dependency on steverhoades/oauth2-openid-connect-server +(low maintenance) + +# Version 3 to 4 +- PHP version requirement was bumped to v8.0 to enable updating important +dependent packages like 'league/oauth2-server' which has already moved to +PHPv8 between their minor releases. +- SimpleSAMLphp version used during development was bumped v2.0 + +# Version 2 to 3 +- Module code was refactored to make it compatible with SimpleSAMLphp v2 +- The default key name was changed from oidc_module.pem to oidc_module.key. +If you don't set a custom key name using the option 'privatekey' in a module +config file, make sure to change the file name of the key from +oidc_module.pem to oidc_module.key. +- Removed config option 'alwaysIssueRefreshToken' +- Removed config option 'alwaysAddClaimsToIdToken' + +# Version 1 to 2 + +There are many DB changes that need to be applied. Perform the migration by +logging in as an SSP admin to +https://server/simplesaml/module.php/oidc/install.php + +An SSP admin should now use +https://server/simplesaml/module.php/oidc/admin-clients/ to manage clients. +The previous `/clients/` path is for authorized users. + +Review the changes to `config-templates/module_oidc.php` and apply relevant +changes to your configuration. For example, claim types are now supported. + +In version 1, in authorization code flow, user claims were always included in +ID token, instead of only including them if the access token was not released, +as per specification. Since changing this behavior is a potential breaking +change for Relying Parties, in version 2 a config option +'alwaysAddClaimsToIdToken' is introduced to enable OpenID Providers to keep +the behavior from version 1 by setting it to 'true'. +If 'alwaysAddClaimsToIdToken' is set to 'false', user claims will only be added +to ID token if access token was not released. If an access token was released, +user claims will have to be fetched from the 'userinfo' endpoint. +Note that this option has only applied to authorization code flow since +implicit flow was not available in version 1. If you are to use the spec +compliant behavior, make sure to warn existing Relying Parties about the change. + +Similarly, in version 1, in authorization code flow, the refresh token was +always released, instead of only releasing it if the client specifically +requested it using the 'offline_access' scope. Since changing this +behavior is a potential breaking change for Relying Parties, in version 2 +a config option 'alwaysIssueRefreshToken' is introduced to enable OpenID +Providers to keep the behavior from version 1 by setting it to 'true'. +If 'alwaysIssueRefreshToken' is set to 'false', refresh token will be released +only if it was requested using 'offline_access' scope. If you are to use the +spec compliant behavior, make sure to warn existing Relying Parties about +the change. Note that in that case the client must have the +'offline_access' scope registered. + +Token endpoint was renamed from '.../access_token.php' to '.../token.php'. +This is a potential breaking change for clients that do not fetch +OP configuration from the /.well-known/openid-configuration URI dynamically, but +instead hardcode endpoints in their configuration. You should probably warn +existing Relying Parties about this change. From 02af41b24257b0ee83e189edbb06b6a3cade2e21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Ivan=C4=8Di=C4=87?= Date: Thu, 9 Oct 2025 13:53:15 +0200 Subject: [PATCH 4/8] Remove old markdown files --- CONFORMANCE_TEST.md | 108 ---------- FAQ.md | 12 -- README.md | 473 +------------------------------------------- UPGRADE.md | 182 ----------------- 4 files changed, 1 insertion(+), 774 deletions(-) delete mode 100644 CONFORMANCE_TEST.md delete mode 100644 FAQ.md delete mode 100644 UPGRADE.md diff --git a/CONFORMANCE_TEST.md b/CONFORMANCE_TEST.md deleted file mode 100644 index 53b676c9..00000000 --- a/CONFORMANCE_TEST.md +++ /dev/null @@ -1,108 +0,0 @@ -# Overview - -The OpenID foundation provides conformance tests. This is a guide to setting up and running -them against this SSP module. - -# Running Conformance Tests Locally - -This approach is best when you want to test changes without having to deploy your project - -## Run Conformance Images - -Clone the conformance test git repo, build the software and run it. - -```bash -git clone https://gitlab.com/openid/conformance-suite.git -cd conformance-suite -git checkout release-v5.1.35 -MAVEN_CACHE=./m2 docker-compose -f builder-compose.yml run builder -docker-compose up -``` - -This will start up the Java conformance app and a MongoDB server. You'll need to configure a test. - -Visit https://localhost:8443/ and "Create a new plan". -The Test Plan should be "OpenID Connect Core: Basic Certification Profile Authorization server test" -which is under "Test an OpenID Provider / Authorization Server". - -Then click on the JSON tab and enter the JSON from file `conformance-tests/conformance-basic-local.json`. -This file contains several clients and a OIDC discovery config for running against a local SSP OIDC - -You'll need to get your OIDC SSP image running next - -## Run SSP - -You'll need to run SSP with OIDC on the same docker network as the compliance tests, so they are able to communicate. - -See "Docker Compose" section of the main README. - -## Run Conformance Tests - -The conformance tests are interactive to make you authenticate. Some of the tests require you to clear cookies to -confirm certain test scenarios, while others require you to have session cookies to test the RP signaling to the -OP that the user should reauthenticate. The tests may also redirect you to https://localhost.emobix.co.uk:8443/ -which will resolve to the conformance Java container. You'll need to accept any SSL connection warnings. - -## Run automated tests - -Eventually these test can have -[the browser portion automated](https://gitlab.com/openid/conformance-suite/-/wikis/Design/BrowserControl) -though the Conformance tests authors recommend getting them all to pass first. - -To run basic profile test, launch this command in console inside `simplesamlphp-module-oidc` directory: - -```shell -# Run run-test-plan.py script inside conformance-suite/scripts -# Change the relative path to your conformance-suite installation -# conformance-basic-ci.json contains clients, and browser interactions for automating various tests -# Lines like "oidcc-implicit-certification-test-plan[server_metadata=discovery][client_registration=static_client]" -# indicate the conformance plan to run, and any variants (parameters) are passed in [] - -OIDC_MODULE_FOLDER=. # path to your checkout of the OIDC module -# Basic profile -conformance-suite/scripts/run-test-plan.py \ - --expected-failures-file ${OIDC_MODULE_FOLDER}/conformance-tests/basic-warnings.json \ - --expected-skips-file ${OIDC_MODULE_FOLDER}/conformance-tests/basic-skips.json \ - "oidcc-basic-certification-test-plan[server_metadata=discovery][client_registration=static_client]" \ - ${OIDC_MODULE_FOLDER}/conformance-tests/conformance-basic-ci.json - -# Implicit profile -conformance-suite/scripts/run-test-plan.py \ - --expected-failures-file ${OIDC_MODULE_FOLDER}/conformance-tests/implicit-warnings.json \ - --expected-skips-file ${OIDC_MODULE_FOLDER}/conformance-tests/implicit-skips.json \ - "oidcc-implicit-certification-test-plan[server_metadata=discovery][client_registration=static_client]" \ - ${OIDC_MODULE_FOLDER}/conformance-tests/conformance-implicit-ci.json - -# RP Initiated back channel -conformance-suite/scripts/run-test-plan.py \ - "oidcc-backchannel-rp-initiated-logout-certification-test-plan[response_type=code][client_registration=static_client]" \ - ${OIDC_MODULE_FOLDER}/conformance-tests/conformance-back-channel-logout-ci.json - -conformance-suite/scripts/run-test-plan.py \ - "oidcc-rp-initiated-logout-certification-test-plan[response_type=code][client_registration=static_client]" \ - ${OIDC_MODULE_FOLDER}/conformance-tests/conformance-rp-initiated-logout-ci.json -``` - - - -As prerequisites, you need to run first the docker deploy image for conformance test described in [README.md](README.md) -and the conformance test image. - -# Running Hosted Tests - -OpenID foundation hosts the conformance testing software and allows you to test it against your server. -In this situation your OIDC OP must be accessible to the public internet. - -## Deploy SSP OIDC Image - -The docker image created in the README.md is designed to be used for running the conformance tests. -It contains a sqlite database pre-populated with data that can be used for these tests. -Build and run the image somewhere. - -## Register and Create Conformance Tests - -Visit https://openid.net/certification/instructions/ -You can use the `json` deployment configurations under `conformance-tests` to configure your cloud instances. Update -your `discoveryUrl` to reflect the location you deployed SSP. You may also need to adjust `alias` since that is used -in all client redirect URIs and may conflict with existing test suites. - diff --git a/FAQ.md b/FAQ.md deleted file mode 100644 index fcf288c5..00000000 --- a/FAQ.md +++ /dev/null @@ -1,12 +0,0 @@ -# Set JSON type for claims - -You can set the type of claim by prefixing the name with `int:`, `bool:` or `string:`. If no prefix is set then `string` -is assumed. In the rare event that your custom claim name starts with a prefix (example: `int:mycustomclaim`) you can -add one of the type prefixes (example: `string:int:mycustomclaim`) to force the module to release a claim with the -original prefix in it (example: claim `int:mycustomclaim` of type `string`) - -# Release photo - -The OIDC `picture` claim is an URL, while the `jpegPhoto` LDAP attribute is often a b64 string. To use `jpegPhoto` you -can try using an authproc filter to turn it into a data url by adding `data:image/jpeg;base64,` prefix. The support -for data URLs amongst OIDC client is unknown. \ No newline at end of file diff --git a/README.md b/README.md index 74bfc281..a39b7844 100644 --- a/README.md +++ b/README.md @@ -1,481 +1,10 @@ # simplesamlphp-module-oidc > A SimpleSAMLphp module for OIDC OP support. -This module adds support for the OpenID Provider role from the OpenID Connect protocol -through a SimpleSAMLphp module installable via Composer. It is based on -[OAuth2 Server from the PHP League](https://oauth2.thephpleague.com/). - -Currently supported flows are: -* Authorization Code flow, with PKCE support (response_type 'code') -* Implicit flow (response_type 'id_token token' or 'id_token') -* Refresh Token flow - [![Build Status](https://github.com/simplesamlphp/simplesamlphp-module-oidc/actions/workflows/test.yaml/badge.svg)](https://github.com/simplesamlphp/simplesamlphp-module-oidc/actions/workflows/test.yaml) [![Coverage Status](https://codecov.io/gh/simplesamlphp/simplesamlphp-module-oidc/branch/master/graph/badge.svg)](https://app.codecov.io/gh/simplesamlphp/simplesamlphp-module-oidc) [![SimpleSAMLphp](https://img.shields.io/badge/simplesamlphp-2.3-brightgreen)](https://simplesamlphp.org/) ![Main screen capture](docs/oidc.png) -### Note on OpenID Federation (OIDFed) support - -OpenID Federation support is in "draft" phase, as is the -[specification](https://openid.net/specs/openid-federation-1_0) itself. This means that you can expect breaking changes -in future releases related to OIDFed capabilities. You can enable / disable OIDFed support at any time in the module -configuration. - -Currently, the following OIDFed features are supported: -* automatic client registration using a Request Object (passing it by value) -* federation participation limiting based on Trust Marks -* endpoint for issuing configuration entity statement (statement about itself) -* fetch endpoint for issuing statements about subordinates (registered clients) -* subordinate listing endpoint - -OIDFed support is implemented using the underlying [SimpleSAMLphp OpenID library](https://github.com/simplesamlphp/openid). - -## Version compatibility - -The minor versions of SimpleSAMLphp listed below indicate which versions of SimpleSAMLphp were used for testing -during module development. SimpleSAMLphp has followed semantic versioning for its API since version 2.0. This means, -for example, that v5.* of the OIDC module should work with any v2.* of SimpleSAMLphp. However, please note that -PHP version requirements have changed in minor SimpleSAMLphp releases. - -| OIDC module | Tested SimpleSAMLphp | PHP | Note | -|:------------|:---------------------|:------:|-------------| -| v6.\* | v2.3.\*, v2.4.\* | \>=8.2 | Recommended | -| v5.\* | v2.1.\* | \>=8.1 | | -| v4.\* | v2.0.\* | \>=8.0 | | -| v3.\* | v2.0.\* | \>=7.4 | | -| v2.\* | v1.19.\* | \>=7.4 | | - -### Upgrading? - -If you are upgrading from a previous version, make sure to check the [upgrade guide](UPGRADE.md). - -## Installation - -Installation is as simple as executing: - - composer require simplesamlphp/simplesamlphp-module-oidc - -### Configure the module - -Copy the module configuration template file to the SimpleSAMLphp config directory: - - cp modules/oidc/config/module_oidc.php.dist config/module_oidc.php - -Review all options in the file and edit them as needed for your environment. - -### Configure the database - -This module uses SimpleSAMLphp's database feature to store access/refresh tokens, user data, and other information. -To set this up, edit your `config/config.php` and configure the database-related settings. Ensure you have at least -the following parameters configured: - - 'database.dsn' => 'mysql:host=server;dbname=simplesamlphp;charset=utf8', - 'database.username' => 'user', - 'database.password' => 'password', - -> [!NOTE] -> The module has been tested with and supports SQLite, PostgreSQL, and MySQL databases. - -### Create Protocol / Federation RSA key pairs - -During the authentication flow, the generated ID Token and Access Token will be in the form of signed JSON Web Tokens (JWS). -For signing these tokens, you need to create a public/private RSA key pair, referred to as "OIDC protocol" keys. - -If you plan to use OpenID Federation capabilities, you should create a separate key pair dedicated to OpenID Federation -operations, such as signing Entity Statement JWS. - -Below are sample commands to create key pairs with default file names for both "protocol" and "federation" purposes: - -To generate the private keys without a passphrase: - - openssl genrsa -out cert/oidc_module.key 3072 - openssl genrsa -out cert/oidc_module_federation.key 3072 - -To generate the private keys with a passphrase: - - openssl genrsa -passout pass:myPassPhrase -out cert/oidc_module.key 3072 - openssl genrsa -passout pass:myPassPhrase -out cert/oidc_module_federation.key 3072 - -Next, extract the public key from each private key: - -Without passphrase: - - openssl rsa -in cert/oidc_module.key -pubout -out cert/oidc_module.crt - openssl rsa -in cert/oidc_module_federation.key -pubout -out cert/oidc_module_federation.crt - -With passphrase: - - openssl rsa -in cert/oidc_module.key -passin pass:myPassPhrase -pubout -out cert/oidc_module.crt - openssl rsa -in cert/oidc_module_federation.key -passin pass:myPassPhrase -pubout -out cert/oidc_module_federation.crt - -If you use different file names or a passphrase, be sure to update these settings in the `module_oidc.php` configuration file. - -### Enabling the module - -To enable the module, add `'oidc' => true` to the list of enabled modules in the main SimpleSAMLphp -configuration file, `config/config.php`: - - 'module.enable' => [ - 'exampleauth' => false, - 'core' => true, - 'admin' => true, - 'saml' => true, - // enable oidc module - 'oidc' => true, - ], - -After enabling the module, you must run the database migrations. - -### Run database migrations - -The module includes default SQL migrations that set up the necessary tables in your configured database. -To run these migrations: - -Option 1: Through the web interface - Navigate to the SimpleSAMLphp administration area, go to -`OIDC` > `Database Migrations`, and click the available button. - -Option 2: Through the command line (recommended for automated/scripted deployments): - - php modules/oidc/bin/install.php - -### Protocol Artifacts Caching - -The configured database serves as the primary storage for protocol artifacts, such as access tokens, authorization -codes, refresh tokens, clients, and user data. In production environments, it is recommended to also set up caching -for these artifacts. The cache layer operates in front of the database, improving performance, particularly during -sudden surges of users attempting to authenticate. The implementation leverages the Symfony Cache component, allowing -the use of any compatible Symfony cache adapter. For more details on configuring the protocol cache, refer to the -module configuration file. - -### Relying Party (RP) Administration - -The module lets you manage (create, read, update and delete) approved RPs from the module user interface itself. - -Once the database schema has been created, in the SimpleSAMLphp administration area go to `OIDC` > -`Client Registry`. - -Note that clients can be marked as confidential or public. If the client is not marked as confidential (it is public), -and is using Authorization Code flow, it will have to provide PKCE parameters during the flow. - -Client ID and secret will be generated, and can be seen after the client creation by clicking on the 'show' button. - -### Cron hook - -In order to purge expired tokens, this module requires [cron module](https://simplesamlphp.org/docs/stable/cron:cron) -to be enabled and configured. - -### Endpoint locations - -Once you deploy the module, in the SimpleSAMLphp administration area go to `OIDC` and then select the -Protocol / Federation Settings page to see the available discovery URLs. These URLs can then be used to set up a -`.well-known` URLs (see below). - -### Key rollover - -The module supports defining additional (new) private / public key pair to be published on relevant JWKS endpoint -or contained in relevant JWKS property. In this way, you can "announce" new public key which can then be fetched -by RPs in order to prepare for the switch of the keys (until the switch of keys, all artifacts continue to be -signed with the "old" private key). - -In this way, after RPs fetch new JWKS (JWKS with "old" and "new" key), you can do the switch of keys when you find -appropriate. - -### Note when using Apache web server - -If you are using Apache web server, you might encounter situations in which Apache strips of Authorization header -with Bearer scheme in HTTP requests, which is a known 'issue' (https://github.com/symfony/symfony/issues/19693). -Although we handle this special situation, it has performance implications, so you should add one of the following -Apache configuration snippets to preserve Authorization header in requests: - -```apacheconf -RewriteEngine On -RewriteCond %{HTTP:Authorization} .+ -RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] -``` -or -```apacheconf -SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1 -``` -Choose the one which works for you. If you don't set it, you'll get a warnings about this situation in your logs. - -## Additional considerations -### Private scopes - -This module support the basic OIDC scopes: openid, email, address, phone and profile. -However, you can add your own private scopes in the `module_oidc.php` config file, for example: - -```php - [ - 'private' => [ - 'description' => 'private scope', - 'claim_name_prefix' => '', // Optional prefix for claim names - 'are_multiple_claim_values_allowed' => false, // Allow or disallow multiple values for claims - 'attributes' => ['national_document_id'] - ], - ], -]; -``` - -### Attribute translation - -Default translation table from SAML attributes to OIDC claims is based on -[REFEDS wiki article: "Mapping SAML attributes to OIDC Claims"](https://wiki.refeds.org/display/GROUPS/Mapping+SAML+attributes+to+OIDC+Claims). - -You can change or extend this table in the `module_oidc.php` config file, like in example below. Note that translation -examples use friendly attribute names. If other attribute name format is used, adjust configuration accordingly. - -```php - [ - // Overwrite default translation - 'sub' => [ - 'uid', // added - 'eduPersonPrincipalName', - 'eduPersonTargetedID', - 'eduPersonUniqueId', - ], - // Remove default translation - 'family_name' => [ - ], - - // New claim created from SAML attribute - // Used in previus private scope - 'national_document_id' => [ - 'schacPersonalUniqueId', - ], - ], -]; -``` - -### Auth Proc Filters -This module will not execute standard Auth Proc Filters which are used during regular SAML authN, reason being that -not all expected entities are participating in the authN process (most notably the Service Provider - SP). -Because of that, OIDC module provides its own 'authproc.oidc' configuration option which can be used to designate -specific Auth Proc Filters which will run only during OIDC authN. - -However, there are some considerations. OIDC authN state array will not contain all the keys which are -available during SAML authN, like Service Provider metadata. If you are using an existing filter, make sure it does -not rely on some non-existent state data. At the moment, only the following SAML authN data will be available: -* \['Attributes'\] -* \['Authority'\] -* \['AuthnInstant'\] -* \['Expire'\] - -Source and destination will have entity IDs corresponding to the OP issuer ID and Client ID respectively. -* \['Source'\]\['entityid'\] - contains OpenId Provider issuer ID -* \['Destination'\]\['entityid'\] - contains Relying Party (OIDC Client) ID - -In addition to that, the following OIDC related data will be available in the state array: -* \['Oidc'\]\['OpenIdProviderMetadata'\] - contains information otherwise available from the OIDC configuration URL. -* \['Oidc'\]\['RelyingPartyMetadata'\] - contains information about the OIDC client making the authN request. -* \['Oidc'\]\['AuthorizationRequestParameters'\] - contains relevant authorization request query parameters. - -Auth Proc processing has been tested with a variety of modules including ones that adjust attributes, log -and redirect for user interaction. - -You can add Auth Proc filters in the 'authproc.oidc' config option in the same manner as described in the [Auth Proc -documentation](https://simplesamlphp.org/docs/stable/simplesamlphp-authproc). - -```php - [ - 50 => [ - 'class' => 'core:AttributeAdd', - 'groups' => ['users', 'members'], - ], - ], -]; -``` -### Client registration permissions - -You can allow users to register their own clients. -This is controlled through the `permissions` setting in `module_oidc.php` - -Permissions let the module expose functionality to specific users. In the -below configuration, a user's eduPersonEntitlement attribute is examined. -If the user tries to do something that requires the `client` permission -(such as registering their own client) then they will need one of the -eduPersonEntitlements from the `client` permission array. - -A permission can be disabled by commenting it out. - -```php - \SimpleSAML\Module\oidc\ModuleConfig::OPTION_ADMIN_UI_PERMISSIONS => [ - // Attribute to inspect to determine user's permissions - 'attribute' => 'eduPersonEntitlement', - // Which entitlements allow for registering, editing, delete a client. OIDC clients are owned by the creator - 'client' => ['urn:example:oidc:manage:client'], - ], -``` - -Users can visit the `https://example.com/simplesaml/module.php/oidc/clients/` to create and view their clients. - -## OIDC Discovery Endpoint - -The module offers an OpenID Connect Discovery endpoint at URL: - - https://yourserver/simplesaml/module.php/oidc/.well-known/openid-configuration - -## OpenID Federation Configuration Endpoint - -The module offers an OpenID Federation configuration endpoint at URL: - - https://yourserver/simplesaml/module.php/oidc/.well-known/openid-federation - -### .well-known URLs - -You can configure your web server (Apache, Nginx) in a way to serve the mentioned URLs in a '.well-known' -format. Below are some sample configurations for `openid-configuration`, but you can take the same approach for -`openid-federation`. - -#### nginx - location = /.well-known/openid-configuration { - rewrite ^(.*)$ /simplesaml/module.php/oidc/.well-known/openid-configuration break; - proxy_pass https://localhost; - } - -#### Apache - - RewriteEngine On - RewriteRule ^/.well-known/openid-configuration(.*) /simplesaml/module.php/oidc/.well-known/openid-configuration$1 [PT] - -## Using Docker - -### With current git branch. - -To explore the module using docker run the below command. This will run an SSP image, with the current oidc module -mounted in the container, along with some configuration files. Any code changes you make to your git checkout are -"live" in the container, allowing you to test and iterate different things. - -``` -docker run --name ssp-oidc-dev \ - --mount type=bind,source="$(pwd)",target=/var/simplesamlphp/staging-modules/oidc,readonly \ - -e STAGINGCOMPOSERREPOS=oidc \ - -e COMPOSER_REQUIRE="simplesamlphp/simplesamlphp-module-oidc:@dev" \ - -e SSP_ADMIN_PASSWORD=secret1 \ - --mount type=bind,source="$(pwd)/docker/ssp/module_oidc.php",target=/var/simplesamlphp/config/module_oidc.php,readonly \ - --mount type=bind,source="$(pwd)/docker/ssp/authsources.php",target=/var/simplesamlphp/config/authsources.php,readonly \ - --mount type=bind,source="$(pwd)/docker/ssp/config-override.php",target=/var/simplesamlphp/config/config-override.php,readonly \ - --mount type=bind,source="$(pwd)/docker/ssp/oidc_module.crt",target=/var/simplesamlphp/cert/oidc_module.crt,readonly \ - --mount type=bind,source="$(pwd)/docker/ssp/oidc_module.key",target=/var/simplesamlphp/cert/oidc_module.key,readonly \ - --mount type=bind,source="$(pwd)/docker/apache-override.cf",target=/etc/apache2/sites-enabled/ssp-override.cf,readonly \ - -p 443:443 cirrusid/simplesamlphp:v2.3.5 -``` - -Visit https://localhost/simplesaml/ and confirm you get the default page. -Then navigate to [OIDC screen](https://localhost/simplesaml/module.php/oidc/install.php) -and you can add a client. - -You may view the OIDC configuration endpoint at `https://localhost/.well-known/openid-configuration` - -#### Local Testing with other DBs - -To test local changes against another DB, such as Postgres, we need to: - -* Create a docker network layer -* Run a DB container (and create a DB if one doesn't exist) -* Run SSP and use the DB container - -``` -# Create the network -docker network create ssp-oidc-test -``` - -``` -# Run the db container - docker run --name oidc-db \ - --network ssp-oidc-test \ - -e POSTGRES_PASSWORD=oidcpass \ - -p 25432:5432 \ - -d postgres:15 -``` - -And then use the `docker run` command from `With current git branch` with the following additions - -``` - -e DB.DSN="pgsql:host=oidc-db;dbname=postgres" \ - -e DB.USERNAME="postgres" \ - -e DB.PASSWORD="oidcpass" \ - --network ssp-oidc-test \ - -``` - -#### Testing AuthProc filters - -To perform manual testing of authproc filters, enable the authprocs in `module_oidc.php` that set firstname, sn and performs -a redirect for preprod warning. This setup shows that an authproc can do a redirect and then processing resumes. -Once adjusted, run docker while change the `COMPOSER_REQUIRE` line to - - `-e COMPOSER_REQUIRE="simplesamlphp/simplesamlphp-module-oidc:@dev simplesamlphp/simplesamlphp-module-preprodwarning" \` - -You can register a client from https://oidcdebugger.com/ to test. - -### Build Image to Deploy for Conformance Tests - -Build an image that contains a pre-configured sqlite database. - -```bash -GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD) -# Replace invalid tag characters when doing build -IMAGE_TAG=$(tr '/' '_' <<< $GIT_BRANCH) -docker build -t "simplesamlphp/simplesamlphp-oidc:dev-$IMAGE_TAG" \ - --build-arg OIDC_VERSION=dev-${GIT_BRANCH} \ - -f docker/Dockerfile . - -docker run --name ssp-oidc-dev-image \ - -e SSP_ADMIN_PASSWORD=secret1 \ - -p 443:443 simplesamlphp/simplesamlphp-oidc:dev-$IMAGE_TAG - -``` - -Publish the image somewhere you can retrieve it. -Temporarily, this will occasionally get published into the cirrusid Docker namespace. - -``` -docker tag "simplesamlphp/simplesamlphp-oidc:dev-$IMAGE_TAG" "cirrusid/simplesamlphp-oidc:dev-$IMAGE_TAG" -docker push "cirrusid/simplesamlphp-oidc:dev-$IMAGE_TAG" -``` - -The database is not currently on a share volume, so any changes will get lost if the container restarts. -You may want to back it up. -To dump the database -```bash -docker exec ssp-oidc-dev-image sqlite3 /var/simplesamlphp/data/mydb.sq3 '.dump' > docker/conformance.sql -``` - -Conformance tests are easier to run locally, see the `Docker compose` section and [CONFORMANCE_TEST.md](CONFORMANCE_TEST.md) - -### Docker compose - -Docker compose will run several containers to make it easier to test scenarios. It will build an image -that contains OIDC module. You may remove the ``--build`` argument if you want docker-compose to reuse -previously running container. - -``` -# Use the current branch/git checkout. Composer installs local checkout -OIDC_VERSION=@dev docker-compose -f docker/docker-compose.yml --project-directory . up --build - -# Set OIDC_VERSION to a version that composer can install to use a different version of the module. -OIDC_VERSION=dev-master docker-compose -f docker/docker-compose.yml --project-directory . up --build -``` - -Visit the [OP](https://op.local.stack-dev.cirrusidentity.com/simplesaml/) and confirm a few clients already exist. - -Conformance tests are easier to run locally, see [CONFORMANCE_TEST.md](CONFORMANCE_TEST.md) - -## Running Conformance Tests - -See [CONFORMANCE_TEST.md](CONFORMANCE_TEST.md) - -## Have more questions? - -Check the [FAQ](FAQ.md). +To get started, refer to our [Documentation](docs/oidc.md). diff --git a/UPGRADE.md b/UPGRADE.md deleted file mode 100644 index 81a738ca..00000000 --- a/UPGRADE.md +++ /dev/null @@ -1,182 +0,0 @@ - -# Version 5 to 6 - -## New features -- Caching support for OIDC protocol artifacts like Access Tokens, Authorization Codes, Refresh Tokens, but also - client and user data. The cache layer stands in front of the database store, so it can improve performance, especially - in cases of sudden surge of users trying to authenticate. Implementation is based on Symfony Cache component, so any - compatible Symfony cache adapter can be used. Check the module config file for more information on how to set the - protocol cache. -- Key rollover support - you can now define additional (new) private / public key pair which will be published on -relevant JWKS endpoint or contained in JWKS property. In this way, you can "announce" new public key which can then -be fetched by RPs, and do the switch between "old" and "new" key pair when you find appropriate. -- OpenID Federation capabilities: - - Automatic client registration using a Request Object (passing it by value) - - Federation participation limiting based on Trust Marks - - Endpoint for issuing configuration entity statement (statement about itself) - - Fetch endpoint for issuing statements about subordinates (registered clients) - - (from v6.1) Subordinate listing endpoint - - Clients can now be configured with new properties: - - Entity Identifier - - Supported OpenID Federation Registration Types - - Federation JWKS - - Protocol JWKS, JWKS URI and Signed JWKS URI, - - Registration type (manual, federated_automatic, or other in the future) - - Is Federated flag (indicates participation in federation context) - - Timestamps: created_at, updated_at, expires_at -- Improved AuthProc filter support - - Support authproc filters that need to redirect and later resume processing - - `consent` and `preprodwarning` are two authprocs that redirect for user interaction and are now supported - - Uses SSP's ProcessingChain class for closer alignment with SAML IdP configuration. - - Allows additional configuration of authprocs in the main `config.php` under key `authproc.oidc` -- Authorization endpoint now also supports sending request parameters using HTTP POST method, in addition to GET. -- Added support for passing authorization request parameters as JWTs, specifically - passing a Request Object by Value: -https://openid.net/specs/openid-connect-core-1_0.html#RequestObject -- Added support for `private_key_jwt` client authentication method at token endpoint: -https://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication - -## New configuration options -- (from v6.1) Show `claims_supported` claim in OP Discovery endpoint - you can now choose to show supported claims, -as is recommended by OpenID Connect Discovery specification https://openid.net/specs/openid-connect-discovery-1_0.html. -- (optional) Issuer - you can now override the issuer (OP identifier). If not set, it falls back to current scheme, host -and optionally a port (as in all previous module versions). -- (optional) Protocol caching adapter and its arguments -- (optional) OpenID Federation related options (needed if federation capabilities are to be used): - - enabled or disabled federation capabilities - - valid trust anchors - - authority hints - - federation caching adapter and its arguments - - PKI keys - federation keys used for example to sign federation entity statements - - federation participation limiting based on Trust Marks for RPs - - (from v6.1) own Trust Marks to dynamically fetch - - signer algorithm - - entity statement duration - - organization name - - display name - - description - - keywords - - contacts - - logo URI - - policy URI - - information URI - - homepage URI (renamed to organization_uri in draft-43) - - organization URI - -## Major impact changes - -- PHP version requirement was bumped to v8.2 - -## Medium impact changes - -- Database schema has been updated, so you'll have to run the DB migrations as described in the README file. -- OIDC protocol endpoints ('authorization_endpoint', 'token_endpoint', 'userinfo_endpoint', 'end_session_endpoint', -'jwks_uri') are now available as new routes which use Symfony routing and container mechanism. This was done as an -effort to move to default SimpleSAMLphp way of working with routes and services. New routes are now published by -default in "OP Configuration" endpoint, which is now also available as -`/module.php/oidc/.well-known/openid-configuration`. If you are publishing that URL as a "well-known" URL -('/.well-known/openid-configuration'), make sure to update your web server configuration to reflect that change -(you can refer to README for examples). All old routes (routes served by PHP files in public folder) will stay -available in this version, which should allow all RPs to update OP configuration in time. Old routes will be -removed in version 7. -- If you are using Apache web server: you should check the README file which now contains a note on how to configure -Apache to preserve Authorization HTTP headers with Bearer token scheme (stripping of this header in Apache is a -known 'issue': https://github.com/symfony/symfony/issues/19693). If you don't set this config, you'll now get warnings -about this situation in your logs. -- The new authproc filter processing will look in an additional location for filters, in the main `config.php` under -key `authproc.oidc` -- Removed support for plain OAuth2 Implicit flow (response_type `token`), because of very low usage. Note that the OIDC -Implicit flow is still supported (response_type `id_token token` or `id_token`). - -## Low impact changes - -- In an effort to move to SimpleSAMLphp way of working with user interface (UI), the client management UI was updated -to extend from the SimpleSAMLphp base template. In addition, we have also introduced some configuration overview pages -where you can take a quick view of some of the configuration values for the module. OIDC related pages are now available -from the main SimpleSAMLphp menu in Administration area. - -- The OIDC config template file has been moved from `config-templates/module_oidc.php` to `config/module_oidc.php.dist`. -This is only relevant for new installations, since initially it is needed to copy the template file to default SSP -config dir. README has been updated to reflect that change. - -Below are also some internal changes that should not have impact for the OIDC OP implementors. However, if you are using -this module as a library or extending from it, you will probably encounter breaking changes, since a lot of code -has been refactored: - -- Upgraded to v5 of lcobucci/jwt https://github.com/lcobucci/jwt -- Upgraded to v3 of laminas/laminas-diactoros https://github.com/laminas/laminas-diactoros -- SimpleSAMLphp version used during development was bumped to v2.3 -- In Authorization Code Flow, a new validation was added which checks for 'openid' value in 'scope' parameter. Up to -now, 'openid' value was dynamically added if not present. In Implicit Code Flow this validation was already present. -- Removed importer from legacy OAuth2 module, as it is very unlikely that someone will upgrade from legacy OAuth2 -module to v6 of oidc module. If needed, one can upgrade to earlier versions of oidc module, and then to v6. - -# Version 4 to 5 - -## Major impact changes -- PHP version requirement was bumped to v8.1 - -## Medium impact changes -- Module config options in file 'module_oidc.php' are now using constants for config keys. The values for constants are -taken from the previous version of the module, so theoretically you don't have to rewrite your current config file, -although it is recommended to do so. - -## Low impact changes -- Removed the 'kid' config option which was not utilized in the codebase (from v2 of the module, the 'kid' value is the -fingerprint of the certificate). - -Below are some internal changes that should not have impact for the OIDC OP implementors. However, if you are using -this module as a library or extending from it, you will probably encounter breaking changes, since a lot of code -has been refactored: - -- psalm error level set to 1, which needed a fair amount of code adjustments -- refactored to strict typing whenever possible (psalm can now infer types for >99% of the codebase) -- refactored to PHP v8.* (up to PHP v8.1) code styling whenever possible, like using constructor property promotion, -match expressions... -- removed dependency on steverhoades/oauth2-openid-connect-server (low maintenance) - -# Version 3 to 4 -- PHP version requirement was bumped to v8.0 to enable updating important dependant packages like 'league/oauth2-server' - which has already moved to PHPv8 between their minor releases. -- SimpleSAMLphp version used during development was bumped v2.0 - -# Version 2 to 3 - - Module code was refactored to make it compatible with SimpleSAMLphp v2 - - Default key name was changed from oidc_module.pem to oidc_module.key. If you don't set custom -key name using option 'privatekey' in module config file, make sure to change the file name of the -key from oidc_module.pem to oidc_module.key. - - Removed config option 'alwaysIssueRefreshToken' - - Removed config option 'alwaysAddClaimsToIdToken' - -# Version 1 to 2 - -There are numerous DB changes that need to be applied. Perform the migration by logging in as an SSP admin to -https://server/simplesaml/module.php/oidc/install.php - -An SSP admin should now use https://server/simplesaml/module.php/oidc/admin-clients/ to manage clients. -The previous `/clients/` path is for authorized users. - -Review the changes to `config-templates/module_oidc.php` and apply relevant changes to your configuration. -For example claim types are now supported. - -In version 1, in authorization code flow, user claims were always included in ID token, instead of only -including them if access token was not released, as per specification. Since changing this behavior is a -potential breaking change for Relying Parties, in version 2 a config option 'alwaysAddClaimsToIdToken' is -introduced to enable OpenID Providers to keep the behavior from version 1 by setting it to 'true'. -If 'alwaysAddClaimsToIdToken' is set to 'false', user claims will only be added to ID token if access token was -not released. If access token was released, user claims will have to be fetched from 'userinfo' endpoint. -Note that this option only applies to authorization code flow since implicit flow was not available in version 1. -If you are to use the spec compliant behavior, make sure to warn existing Relying Parties about the change. - -Similarly, in version 1, in authorization code flow, refresh token was always released, instead of only -releasing it if the client specifically requested it using 'offline_access' scope. Since changing this -behavior is a potential breaking change for Relying Parties, in version 2 a config option -'alwaysIssueRefreshToken' is introduced to enable OpenID Providers to keep the behavior from version 1 -by setting it to 'true'. If 'alwaysIssueRefreshToken' is set to 'false', refresh token will be released -only if it was requested using 'offline_access' scope. If you are to use the spec compliant behavior, make -sure to warn existing Relying Parties about the change. Note that in that case the client must have the -'offline_access' scope registered. - -Token endpoint was renamed from '.../access_token.php' to '.../token.php'. This is a potential breaking change -for clients that do not fetch OP configuration from the /.well-known/openid-configuration URI dynamically, but -instead hardcode endpoints in their configuration. You should probably warn existing Relying Parties about this -change. From 7101cca3fbea03663615684fdb9525b3c97063be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Ivan=C4=8Di=C4=87?= Date: Thu, 9 Oct 2025 14:06:55 +0200 Subject: [PATCH 5/8] Lint --- .markdownlint.yml | 4 ++++ README.md | 2 +- docker/nginx-certs/README.md | 15 +++++++++++---- docs/configuration.md | 26 +++++++++++++------------- docs/upgrade.md | 24 +++++++++++++----------- 5 files changed, 42 insertions(+), 29 deletions(-) create mode 100644 .markdownlint.yml diff --git a/.markdownlint.yml b/.markdownlint.yml new file mode 100644 index 00000000..945987bc --- /dev/null +++ b/.markdownlint.yml @@ -0,0 +1,4 @@ +--- +default: true + +MD013: false \ No newline at end of file diff --git a/README.md b/README.md index a39b7844..d89c20b9 100644 --- a/README.md +++ b/README.md @@ -7,4 +7,4 @@ ![Main screen capture](docs/oidc.png) -To get started, refer to our [Documentation](docs/oidc.md). +To get started, refer to our [documentation](docs/oidc.md). diff --git a/docker/nginx-certs/README.md b/docker/nginx-certs/README.md index 31efd918..b14f9111 100644 --- a/docker/nginx-certs/README.md +++ b/docker/nginx-certs/README.md @@ -1,9 +1,16 @@ -Every 90 days these certificates expire. The upstream project/container will refresh its certs occasionally, and we -can sync them here. +# Certificates + +Every 90 days these certificates expire. The upstream project/container +will refresh its certs occasionally, and we can sync them here. ```bash docker pull cirrusid/simplesamlphp:latest -docker run -v $PWD:/opt/tmp/certs cirrusid/simplesamlphp /bin/bash -c 'cp /etc/ssl/certs/${APACHE_CERT_NAME}.key /opt/tmp/certs/default.crt && cp /etc/ssl/private/${APACHE_CERT_NAME}.key /opt/tmp/certs/default.key && openssl x509 -noout -enddate -in /opt/tmp/certs/default.crt > /opt/tmp/certs/expiration' +docker run -v $PWD:/opt/tmp/certs cirrusid/simplesamlphp /bin/bash -c \ +'cp /etc/ssl/certs/${APACHE_CERT_NAME}.key /opt/tmp/certs/default.crt && +cp /etc/ssl/private/${APACHE_CERT_NAME}.key /opt/tmp/certs/default.key && +openssl x509 -noout -enddate -in /opt/tmp/certs/default.crt > +/opt/tmp/certs/expiration' ``` -The file `expiration` will get updated with the current expiration date of the certificates. +The file `expiration` will get updated with the current expiration date of +the certificates. diff --git a/docs/configuration.md b/docs/configuration.md index 3dc13821..987a944b 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -32,6 +32,7 @@ After you create the database schema, go to the SimpleSAMLphp admin area: - OIDC > Client Registry Notes: + - Clients can be public or confidential. - Public clients using Authorization Code flow must send PKCE parameters. - Client ID and secret are generated; use the "show" button to reveal. @@ -39,8 +40,7 @@ Notes: ## Cron integration Enable and configure the SimpleSAMLphp cron module to purge expired tokens: - -- https://simplesamlphp.org/docs/stable/cron/cron.html +[cron](https://simplesamlphp.org/docs/stable/cron/cron.html) ## Endpoint locations and well-known URLs @@ -51,9 +51,9 @@ After deployment, visit the SimpleSAMLphp admin area: There you can see discovery URLs. Typical discovery endpoints are: - OpenID Connect Discovery: - https://yourserver/simplesaml/module.php/oidc/.well-known/openid-configuration +[https://yourserver/simplesaml/module.php/oidc/.well-known/openid-configuration](https://yourserver/simplesaml/module.php/oidc/.well-known/openid-configuration) - OpenID Federation configuration: - https://yourserver/simplesaml/module.php/oidc/.well-known/openid-federation +[https://yourserver/simplesaml/module.php/oidc/.well-known/openid-federation](https://yourserver/simplesaml/module.php/oidc/.well-known/openid-federation) You may publish these as ".well-known" URLs at the web root using your web server. For example, for `openid-configuration`: @@ -163,21 +163,21 @@ all SAML entities are present (like a Service Provider). Instead, use the The OIDC authN state does not include all keys present in SAML authN. Available SAML-like keys include: -- ['Attributes'] -- ['Authority'] -- ['AuthnInstant'] -- ['Expire'] +- \['Attributes'\] +- \['Authority'\] +- \['AuthnInstant'\] +- \['Expire'\] Source and Destination entity IDs correspond to OP issuer and Client ID: -- ['Source']['entityid'] → OP issuer ID -- ['Destination']['entityid'] → RP (client) ID +- \['Source'\]\['entityid'\] → OP issuer ID +- \['Destination'\]\['entityid'\] → RP (client) ID Additional OIDC data in the state: -- ['Oidc']['OpenIdProviderMetadata'] -- ['Oidc']['RelyingPartyMetadata'] -- ['Oidc']['AuthorizationRequestParameters'] +- \['Oidc'\]\['OpenIdProviderMetadata'\] +- \['Oidc'\]\['RelyingPartyMetadata'\] +- \['Oidc'\]\['AuthorizationRequestParameters'\] Example filter configuration: diff --git a/docs/upgrade.md b/docs/upgrade.md index 1475f6b5..027262c2 100644 --- a/docs/upgrade.md +++ b/docs/upgrade.md @@ -6,6 +6,7 @@ apply those relevant to your deployment. ## Version 5 to 6 New features: + - Caching support for OIDC protocol artifacts like Access Tokens, Authorization Codes, Refresh Tokens, but also client and user data. The cache layer stands in front of the database store, so it can @@ -48,17 +49,17 @@ find appropriate. HTTP POST method, in addition to GET. - Added support for passing authorization request parameters as JWTs, specifically - passing a Request Object by Value: - https://openid.net/specs/openid-connect-core-1_0.html#RequestObject +[https://openid.net/specs/openid-connect-core-1_0.html#RequestObject](https://openid.net/specs/openid-connect-core-1_0.html#RequestObject) - Added support for `private_key_jwt` client authentication method at token endpoint: - https://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication +[https://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication](https://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication) New configuration options: - (from v6.1) Show `claims_supported` claim in OP Discovery endpoint - you can now choose to show supported claims, as is recommended by OpenID Connect Discovery specification -https://openid.net/specs/openid-connect-discovery-1_0.html. +[https://openid.net/specs/openid-connect-discovery-1_0.html](https://openid.net/specs/openid-connect-discovery-1_0.html). - (optional) Issuer - you can now override the issuer (OP identifier). If not set, it falls back to the current scheme, host, and optionally a port (as in all previous module versions). @@ -110,7 +111,7 @@ Old routes will be removed in version 7. - If you are using Apache web server: you should check the README file which now contains a note on how to configure Apache to preserve Authorization HTTP headers with a Bearer token scheme (stripping of this header in Apache is a -known 'issue': https://github.com/symfony/symfony/issues/19693). If you don't +known [issue](https://github.com/symfony/symfony/issues/19693)). If you don't set this config, you'll now get warnings about this situation in your logs. The new authproc filter processing will look in an additional location for filters, in the main `config.php` under key `authproc.oidc` @@ -118,7 +119,7 @@ filters, in the main `config.php` under key `authproc.oidc` because of very low usage. Note that the OIDC Implicit flow is still supported (response_type `id_token token` or `id_token`). -Low-impact changes +Low-impact changes: - In an effort to move to SimpleSAMLphp way of working with user interface (UI), the client management UI was updatedto extend from the SimpleSAMLphp base @@ -136,9 +137,8 @@ OIDC OP implementors. However, if you are using this module as a library or extending from it, you will probably encounter breaking changes, since a lot of code has been refactored: -- Upgraded to v5 of lcobucci/jwt https://github.com/lcobucci/jwt -- Upgraded to v3 of laminas/laminas-diactoros -https://github.com/laminas/laminas-diactoros +- Upgraded to v5 of [lcobucci/jwt](https://github.com/lcobucci/jwt) +- Upgraded to v3 of [laminas/laminas-diactoros](https://github.com/laminas/laminas-diactoros) - SimpleSAMLphp version used during development was bumped to v2.3 - In Authorization Code Flow, a new validation was added which checks for 'openid' value in the 'scope' parameter. Up to now, the 'openid' value was @@ -181,12 +181,14 @@ like using constructor property promotion, match expressions... (low maintenance) # Version 3 to 4 + - PHP version requirement was bumped to v8.0 to enable updating important dependent packages like 'league/oauth2-server' which has already moved to PHPv8 between their minor releases. - SimpleSAMLphp version used during development was bumped v2.0 # Version 2 to 3 + - Module code was refactored to make it compatible with SimpleSAMLphp v2 - The default key name was changed from oidc_module.pem to oidc_module.key. If you don't set a custom key name using the option 'privatekey' in a module @@ -199,11 +201,11 @@ oidc_module.pem to oidc_module.key. There are many DB changes that need to be applied. Perform the migration by logging in as an SSP admin to -https://server/simplesaml/module.php/oidc/install.php +[https://server/simplesaml/module.php/oidc/install.php](https://server/simplesaml/module.php/oidc/install.php) An SSP admin should now use -https://server/simplesaml/module.php/oidc/admin-clients/ to manage clients. -The previous `/clients/` path is for authorized users. +[https://server/simplesaml/module.php/oidc/admin-clients/](https://server/simplesaml/module.php/oidc/admin-clients/) +to manage clients. The previous `/clients/` path is for authorized users. Review the changes to `config-templates/module_oidc.php` and apply relevant changes to your configuration. For example, claim types are now supported. From 4dc6f32dfa1b8341348f1348d761ee6f3025ad36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Ivan=C4=8Di=C4=87?= Date: Thu, 9 Oct 2025 14:22:28 +0200 Subject: [PATCH 6/8] Lint --- README.md | 5 +++-- docs/configuration.md | 10 +++++----- docs/conformance.md | 8 ++++---- docs/docker.md | 9 +++++---- docs/oidc.md | 20 ++++++++++++-------- docs/upgrade.md | 16 ++++++++-------- 6 files changed, 37 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index d89c20b9..37b833b6 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ -# simplesamlphp-module-oidc +# SimpleSAMLphp Module OIDC + > A SimpleSAMLphp module for OIDC OP support. -[![Build Status](https://github.com/simplesamlphp/simplesamlphp-module-oidc/actions/workflows/test.yaml/badge.svg)](https://github.com/simplesamlphp/simplesamlphp-module-oidc/actions/workflows/test.yaml) +[![Build Status](https://github.com/simplesamlphp/simplesamlphp-module-oidc/actions/workflows/test.yaml/badge.svg)](https://github.com/simplesamlphp/simplesamlphp-module-oidc/actions/workflows/test.yaml) [![Coverage Status](https://codecov.io/gh/simplesamlphp/simplesamlphp-module-oidc/branch/master/graph/badge.svg)](https://app.codecov.io/gh/simplesamlphp/simplesamlphp-module-oidc) [![SimpleSAMLphp](https://img.shields.io/badge/simplesamlphp-2.3-brightgreen)](https://simplesamlphp.org/) diff --git a/docs/configuration.md b/docs/configuration.md index 987a944b..3e3084dd 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -84,8 +84,8 @@ perform the key switch. ## Apache Authorization header note -Apache may strip the `Authorization` header (Bearer) from requests, a known -issue: https://github.com/symfony/symfony/issues/19693 +Apache may strip the `Authorization` header (Bearer) from requests (a known +[issue](https://github.com/symfony/symfony/issues/19693)). Although the module includes a fallback, it has performance implications. Configure Apache to preserve the header using one of these snippets: @@ -126,8 +126,8 @@ $config = [ ## Attribute translation -Default SAML-to-OIDC claim mapping follows the REFEDS guidance: -https://wiki.refeds.org/display/GROUPS/Mapping+SAML+attributes+to+OIDC+Claims +Default SAML-to-OIDC claim mapping follows the +[REFEDS guidance](https://wiki.refeds.org/display/GROUPS/Mapping+SAML+attributes+to+OIDC+Claims). You can change or extend this mapping in `module_oidc.php`. Example: @@ -217,4 +217,4 @@ $config = [ Users can visit the following link for administration: -- https://example.com/simplesaml/module.php/oidc/clients/ +- [https://example.com/simplesaml/module.php/oidc/clients/](https://example.com/simplesaml/module.php/oidc/clients/) diff --git a/docs/conformance.md b/docs/conformance.md index c7d2708a..81863b15 100644 --- a/docs/conformance.md +++ b/docs/conformance.md @@ -24,7 +24,7 @@ docker-compose up This starts the Java conformance app and a MongoDB server. Then: -- Visit https://localhost:8443/ +- Visit [https://localhost:8443/](https://localhost:8443/) - Create a new plan: "OpenID Connect Core: Basic Certification Profile Authorization server test" - Click the JSON tab and paste @@ -48,8 +48,8 @@ warnings as needed. ### Run automated tests -Once manual tests pass, you can automate the browser portion: -https://gitlab.com/openid/conformance-suite/-/wikis/Design/BrowserControl +Once manual tests pass, you can +[automate the browser portion](https://gitlab.com/openid/conformance-suite/-/wikis/Design/BrowserControl). From the `simplesamlphp-module-oidc` directory: @@ -97,7 +97,7 @@ pre-populated with data for the tests. Build and run the image. ### Register and create conformance tests -Visit https://openid.net/certification/instructions/ +Visit [https://openid.net/certification/instructions/](https://openid.net/certification/instructions/). Use the `json` configs under `conformance-tests` to configure your cloud instances. Update `discoveryUrl` to the deployed location. Adjust `alias` diff --git a/docs/docker.md b/docs/docker.md index 0d7e1aac..ccd6c106 100644 --- a/docs/docker.md +++ b/docs/docker.md @@ -30,11 +30,11 @@ docker run --name ssp-oidc-dev \ Then visit: -- https://localhost/simplesaml/ +- [https://localhost/simplesaml/](https://localhost/simplesaml/) The OIDC configuration endpoint is available at: -- https://localhost/.well-known/openid-configuration +- [https://localhost/.well-known/openid-configuration](https://localhost/.well-known/openid-configuration) ## Local testing with other DBs @@ -78,7 +78,8 @@ When running Docker, adjust `COMPOSER_REQUIRE` to include the module: simplesamlphp/simplesamlphp-module-preprodwarning" ``` -You can register a client from https://oidcdebugger.com/ to test. +You can register a client from +[https://oidcdebugger.com/](https://oidcdebugger.com/) to test. ## Build image for conformance tests @@ -132,4 +133,4 @@ OIDC_VERSION=dev-master docker-compose -f docker/docker-compose.yml --project-di Visit the OP and verify a few clients exist: -- https://op.local.stack-dev.cirrusidentity.com/simplesaml/ +- [https://op.local.stack-dev.cirrusidentity.com/simplesaml/](https://op.local.stack-dev.cirrusidentity.com/simplesaml/) diff --git a/docs/oidc.md b/docs/oidc.md index 2111d1f0..6b38c22a 100644 --- a/docs/oidc.md +++ b/docs/oidc.md @@ -6,6 +6,7 @@ and is based on the [OAuth2 Server from the PHP League](https://oauth2.thephpleague.com/). Supported flows: + - Authorization Code, with PKCE (response_type: `code`) - Implicit (response_type: `id_token token` or `id_token`) - Refresh Token @@ -21,6 +22,7 @@ capabilities. OIDFed can be enabled or disabled in the module configuration. Currently supported OIDFed features: + - Automatic client registration using a Request Object (by value) - Federation participation limiting based on Trust Marks - Endpoint for issuing a configuration entity statement (about itself) @@ -34,14 +36,16 @@ OIDFed is implemented using the Minor versions listed show which SimpleSAMLphp versions were used during module development. SimpleSAMLphp follows semantic versioning for its -API since v2.0. For example, v5.* of the OIDC module should work with -any v2.* of SimpleSAMLphp. PHP version requirements may differ. - -- OIDC v6.* → SimpleSAMLphp v2.3.*, v2.4.* → PHP >= 8.2 (recommended) -- OIDC v5.* → SimpleSAMLphp v2.1.* → PHP >= 8.1 -- OIDC v4.* → SimpleSAMLphp v2.0.* → PHP >= 8.0 -- OIDC v3.* → SimpleSAMLphp v2.0.* → PHP >= 7.4 -- OIDC v2.* → SimpleSAMLphp v1.19.* → PHP >= 7.4 +API since v2.0. For example, v5.\* of the OIDC module should work with +any v2.\* of SimpleSAMLphp. PHP version requirements may differ. + +| OIDC module | Tested SimpleSAMLphp | PHP | Note | +|:------------|:---------------------|:------:|-------------| +| v6.\* | v2.3.\*, v2.4.\* | \>=8.2 | Recommended | +| v5.\* | v2.1.\* | \>=8.1 | | +| v4.\* | v2.0.\* | \>=8.0 | | +| v3.\* | v2.0.\* | \>=7.4 | | +| v2.\* | v1.19.\* | \>=7.4 | | Upgrading? See the [upgrade guide](upgrade.md). diff --git a/docs/upgrade.md b/docs/upgrade.md index 027262c2..44ec5f9a 100644 --- a/docs/upgrade.md +++ b/docs/upgrade.md @@ -1,7 +1,7 @@ # Upgrade guide This is an upgrade guide from versions 1 → 6. Review the changes and -apply those relevant to your deployment. +apply those relevant to your deployment. ## Version 5 to 6 @@ -149,7 +149,7 @@ someone will upgrade from the legacy OAuth2 module to v6 of oidc module. If needed, one can upgrade to earlier versions of the `oidc` module, and then to v6. -# Version 4 to 5 +## Version 4 to 5 Major impact changes: @@ -180,14 +180,14 @@ like using constructor property promotion, match expressions... - removed dependency on steverhoades/oauth2-openid-connect-server (low maintenance) -# Version 3 to 4 +## Version 3 to 4 - PHP version requirement was bumped to v8.0 to enable updating important dependent packages like 'league/oauth2-server' which has already moved to PHPv8 between their minor releases. - SimpleSAMLphp version used during development was bumped v2.0 -# Version 2 to 3 +## Version 2 to 3 - Module code was refactored to make it compatible with SimpleSAMLphp v2 - The default key name was changed from oidc_module.pem to oidc_module.key. @@ -197,7 +197,7 @@ oidc_module.pem to oidc_module.key. - Removed config option 'alwaysIssueRefreshToken' - Removed config option 'alwaysAddClaimsToIdToken' -# Version 1 to 2 +## Version 1 to 2 There are many DB changes that need to be applied. Perform the migration by logging in as an SSP admin to @@ -237,6 +237,6 @@ the change. Note that in that case the client must have the Token endpoint was renamed from '.../access_token.php' to '.../token.php'. This is a potential breaking change for clients that do not fetch -OP configuration from the /.well-known/openid-configuration URI dynamically, but -instead hardcode endpoints in their configuration. You should probably warn -existing Relying Parties about this change. +OP configuration from the /.well-known/openid-configuration URI dynamically, +but instead hardcode endpoints in their configuration. You should probably +warn existing Relying Parties about this change. From 82b6a90ac5b7b69bb31fd0e6e323e00047f51d33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Ivan=C4=8Di=C4=87?= Date: Thu, 9 Oct 2025 14:25:52 +0200 Subject: [PATCH 7/8] Lint --- docs/docker.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/docker.md b/docs/docker.md index ccd6c106..f4923681 100644 --- a/docs/docker.md +++ b/docs/docker.md @@ -40,13 +40,13 @@ The OIDC configuration endpoint is available at: You can test it against another database such as PostgreSQL. -1) Create a Docker network: +1 - Create a Docker network: ```bash docker network create ssp-oidc-test ``` -2) Run a DB container: +2 - Run a DB container: ```bash docker run --name oidc-db \ @@ -56,7 +56,7 @@ docker run --name oidc-db \ -d postgres:15 ``` -3) Run SSP (from the prior command) with these additions: +3 - Run SSP (from the prior command) with these additions: ```bash -e DB.DSN="pgsql:host=oidc-db;dbname=postgres" \ From fc8bae6bd96403ab0951524ad04d3d015e295ea0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Ivan=C4=8Di=C4=87?= Date: Thu, 9 Oct 2025 14:29:40 +0200 Subject: [PATCH 8/8] Lint --- docs/upgrade.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/upgrade.md b/docs/upgrade.md index 44ec5f9a..65d1d219 100644 --- a/docs/upgrade.md +++ b/docs/upgrade.md @@ -133,7 +133,7 @@ This is only relevant for new installations, since initially it is necessary to copy the template file to the default SSP config dir. Below are also some internal changes that should not have an impact on the -OIDC OP implementors. However, if you are using this module as a library or +OIDC OP implementers. However, if you are using this module as a library or extending from it, you will probably encounter breaking changes, since a lot of code has been refactored: @@ -168,7 +168,7 @@ Low-impact changes: (from v2 of the module, the 'kid' value is the fingerprint of the certificate). Below are some internal changes that should not have an impact on the OIDC OP -implementors. However, if you are using this module as a library or extending +implementers. However, if you are using this module as a library or extending from it, you will probably encounter breaking changes, since a lot of code has been refactored: