From 04993ebb27dbbaf4c8c5514540027bee519c525e Mon Sep 17 00:00:00 2001 From: Brock H Caldwell Date: Fri, 11 Jul 2025 11:27:34 -0500 Subject: [PATCH] wip: working oidc login --- .env | 6 + composer.json | 5 +- composer.lock | 589 +++++++++++++++++- config/bundles.php | 1 + config/packages/drenso_oidc.yaml | 19 + config/packages/security.yaml | 15 +- .../Controller/Web/LoginController.php | 9 +- .../Controller/Web/LoginOidcController.php | 32 + .../Framework/Security/OidcUserProvider.php | 55 ++ symfony.lock | 12 + 10 files changed, 726 insertions(+), 17 deletions(-) create mode 100644 config/packages/drenso_oidc.yaml create mode 100644 src/User/Framework/Controller/Web/LoginOidcController.php create mode 100644 src/User/Framework/Security/OidcUserProvider.php diff --git a/.env b/.env index 5e589ea..2275a9d 100644 --- a/.env +++ b/.env @@ -42,3 +42,9 @@ REDIS_HOST=redis://redis ###> symfony/mailer ### MAILER_DSN=null://null ###< symfony/mailer ### + +###> drenso/symfony-oidc-bundle ### +OIDC_WELL_KNOWN_URL="Enter the .well-known url for the OIDC provider" +OIDC_CLIENT_ID="Enter your OIDC client id" +OIDC_CLIENT_SECRET="Enter your OIDC client secret" +###< drenso/symfony-oidc-bundle ### diff --git a/composer.json b/composer.json index e7a4200..65056bb 100644 --- a/composer.json +++ b/composer.json @@ -16,6 +16,7 @@ "doctrine/doctrine-migrations-bundle": "^3.4", "doctrine/orm": "^3.3", "dragonmantank/cron-expression": "^3.4", + "drenso/symfony-oidc-bundle": "^4.2", "guzzlehttp/guzzle": "^7.9", "league/pipeline": "^1.1", "nesbot/carbon": "^3.9", @@ -36,6 +37,7 @@ "symfony/flex": "^2", "symfony/form": "7.3.*", "symfony/framework-bundle": "7.3.*", + "symfony/http-client": "7.3.*", "symfony/ldap": "7.3.*", "symfony/mailer": "7.3.*", "symfony/mercure-bundle": "^0.3.9", @@ -54,7 +56,8 @@ "symfonycasts/reset-password-bundle": "^1.23", "symfonycasts/tailwind-bundle": "^0.10.0", "twig/extra-bundle": "^2.12|^3.0", - "twig/twig": "^2.12|^3.0" + "twig/twig": "^2.12|^3.0", + "web-token/jwt-library": "^4.0" }, "config": { "allow-plugins": { diff --git a/composer.lock b/composer.lock index 8bcaf23..152f51d 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "f368fdd2e0f36d53131785b857200062", + "content-hash": "bfbdc7ee820da20b824f4b1933fe967b", "packages": [ { "name": "1tomany/rich-bundle", @@ -167,6 +167,66 @@ "abandoned": true, "time": "2022-03-30T09:27:43+00:00" }, + { + "name": "brick/math", + "version": "0.13.1", + "source": { + "type": "git", + "url": "https://github.com/brick/math.git", + "reference": "fc7ed316430118cc7836bf45faff18d5dfc8de04" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/brick/math/zipball/fc7ed316430118cc7836bf45faff18d5dfc8de04", + "reference": "fc7ed316430118cc7836bf45faff18d5dfc8de04", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.2", + "phpunit/phpunit": "^10.1", + "vimeo/psalm": "6.8.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Brick\\Math\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Arbitrary-precision arithmetic library", + "keywords": [ + "Arbitrary-precision", + "BigInteger", + "BigRational", + "arithmetic", + "bigdecimal", + "bignum", + "bignumber", + "brick", + "decimal", + "integer", + "math", + "mathematics", + "rational" + ], + "support": { + "issues": "https://github.com/brick/math/issues", + "source": "https://github.com/brick/math/tree/0.13.1" + }, + "funding": [ + { + "url": "https://github.com/BenMorel", + "type": "github" + } + ], + "time": "2025-03-29T13:50:30+00:00" + }, { "name": "carbonphp/carbon-doctrine-types", "version": "2.1.0", @@ -1883,6 +1943,93 @@ ], "time": "2024-10-09T13:47:03+00:00" }, + { + "name": "drenso/symfony-oidc-bundle", + "version": "v4.2.0", + "source": { + "type": "git", + "url": "https://github.com/Drenso/symfony-oidc.git", + "reference": "6da6a17e206487646799489a1c1dce18ed2f10eb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Drenso/symfony-oidc/zipball/6da6a17e206487646799489a1c1dce18ed2f10eb", + "reference": "6da6a17e206487646799489a1c1dce18ed2f10eb", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-filter": "*", + "ext-hash": "*", + "ext-json": "*", + "ext-mbstring": "*", + "lcobucci/jwt": "^5.0", + "php": ">=8.1", + "phpseclib/phpseclib": "^3.0.36", + "psr/clock": "^1.0", + "psr/container": "^1.1 || ^2.0", + "psr/log": "^1.1 || ^2.0 || ^3.0", + "symfony/config": "^5.4 || ^6.3 || ^7.0", + "symfony/dependency-injection": "^5.4 || ^6.3 || ^7.0", + "symfony/event-dispatcher": "^5.4 || ^6.3 || ^7.0", + "symfony/http-foundation": "^5.4 || ^6.3 || ^7.0", + "symfony/http-kernel": "^5.4 || ^6.3 || ^7.0", + "symfony/property-access": "^5.4 || ^6.3 || ^7.0", + "symfony/security-bundle": "^5.4 || ^6.3 || ^7.0", + "symfony/security-core": "^5.4 || ^6.3 || ^7.0", + "symfony/security-http": "^5.4 || ^6.3 || ^7.0", + "symfony/string": "^5.4 || ^6.3 || ^7.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "3.75.0", + "phpstan/extension-installer": "1.4.3", + "phpstan/phpstan": "2.1.17", + "phpstan/phpstan-deprecation-rules": "^2.0", + "rector/rector": "2.0.18", + "symfony/cache": "^5.4 || ^6.3 || ^7.0", + "symfony/translation-contracts": "^2.0 || ^3.0" + }, + "suggest": { + "symfony/cache": "When installed, IdP information will be automatically cached" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "v3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Drenso\\OidcBundle\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Bob van de Vijver", + "email": "bob@drenso.nl" + }, + { + "name": "Tobias Feijten", + "email": "tobias@drenso.nl" + } + ], + "description": "OpenID connect bundle for Symfony", + "homepage": "https://gitlab.drenso.nl/intern/symfony-oidc", + "keywords": [ + "OpenID Connect", + "oidc", + "symfony" + ], + "support": { + "issues": "https://github.com/Drenso/symfony-oidc/issues", + "source": "https://github.com/Drenso/symfony-oidc/tree/v4.2.0" + }, + "time": "2025-06-19T09:43:57+00:00" + }, { "name": "egulias/email-validator", "version": "4.0.4", @@ -2998,6 +3145,123 @@ }, "time": "2024-02-19T18:29:05+00:00" }, + { + "name": "paragonie/constant_time_encoding", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/paragonie/constant_time_encoding.git", + "reference": "df1e7fde177501eee2037dd159cf04f5f301a512" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/df1e7fde177501eee2037dd159cf04f5f301a512", + "reference": "df1e7fde177501eee2037dd159cf04f5f301a512", + "shasum": "" + }, + "require": { + "php": "^8" + }, + "require-dev": { + "phpunit/phpunit": "^9", + "vimeo/psalm": "^4|^5" + }, + "type": "library", + "autoload": { + "psr-4": { + "ParagonIE\\ConstantTime\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com", + "role": "Maintainer" + }, + { + "name": "Steve 'Sc00bz' Thomas", + "email": "steve@tobtu.com", + "homepage": "https://www.tobtu.com", + "role": "Original Developer" + } + ], + "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)", + "keywords": [ + "base16", + "base32", + "base32_decode", + "base32_encode", + "base64", + "base64_decode", + "base64_encode", + "bin2hex", + "encoding", + "hex", + "hex2bin", + "rfc4648" + ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/constant_time_encoding/issues", + "source": "https://github.com/paragonie/constant_time_encoding" + }, + "time": "2024-05-08T12:36:18+00:00" + }, + { + "name": "paragonie/random_compat", + "version": "v9.99.100", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a", + "shasum": "" + }, + "require": { + "php": ">= 7" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*", + "vimeo/psalm": "^1" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "polyfill", + "pseudorandom", + "random" + ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/random_compat/issues", + "source": "https://github.com/paragonie/random_compat" + }, + "time": "2020-10-15T08:29:30+00:00" + }, { "name": "php-http/cache-plugin", "version": "2.0.1", @@ -3661,6 +3925,116 @@ }, "time": "2024-11-09T15:12:26+00:00" }, + { + "name": "phpseclib/phpseclib", + "version": "3.0.46", + "source": { + "type": "git", + "url": "https://github.com/phpseclib/phpseclib.git", + "reference": "56483a7de62a6c2a6635e42e93b8a9e25d4f0ec6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/56483a7de62a6c2a6635e42e93b8a9e25d4f0ec6", + "reference": "56483a7de62a6c2a6635e42e93b8a9e25d4f0ec6", + "shasum": "" + }, + "require": { + "paragonie/constant_time_encoding": "^1|^2|^3", + "paragonie/random_compat": "^1.4|^2.0|^9.99.99", + "php": ">=5.6.1" + }, + "require-dev": { + "phpunit/phpunit": "*" + }, + "suggest": { + "ext-dom": "Install the DOM extension to load XML formatted public keys.", + "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.", + "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.", + "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.", + "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations." + }, + "type": "library", + "autoload": { + "files": [ + "phpseclib/bootstrap.php" + ], + "psr-4": { + "phpseclib3\\": "phpseclib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jim Wigginton", + "email": "terrafrost@php.net", + "role": "Lead Developer" + }, + { + "name": "Patrick Monnerat", + "email": "pm@datasphere.ch", + "role": "Developer" + }, + { + "name": "Andreas Fischer", + "email": "bantu@phpbb.com", + "role": "Developer" + }, + { + "name": "Hans-Jürgen Petrich", + "email": "petrich@tronic-media.com", + "role": "Developer" + }, + { + "name": "Graham Campbell", + "email": "graham@alt-three.com", + "role": "Developer" + } + ], + "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", + "homepage": "http://phpseclib.sourceforge.net", + "keywords": [ + "BigInteger", + "aes", + "asn.1", + "asn1", + "blowfish", + "crypto", + "cryptography", + "encryption", + "rsa", + "security", + "sftp", + "signature", + "signing", + "ssh", + "twofish", + "x.509", + "x509" + ], + "support": { + "issues": "https://github.com/phpseclib/phpseclib/issues", + "source": "https://github.com/phpseclib/phpseclib/tree/3.0.46" + }, + "funding": [ + { + "url": "https://github.com/terrafrost", + "type": "github" + }, + { + "url": "https://www.patreon.com/phpseclib", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpseclib/phpseclib", + "type": "tidelift" + } + ], + "time": "2025-06-26T16:29:55+00:00" + }, { "name": "phpstan/phpdoc-parser", "version": "2.1.0", @@ -4383,6 +4757,115 @@ ], "time": "2023-12-12T12:06:11+00:00" }, + { + "name": "spomky-labs/pki-framework", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/Spomky-Labs/pki-framework.git", + "reference": "eced5b5ce70518b983ff2be486e902bbd15135ae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Spomky-Labs/pki-framework/zipball/eced5b5ce70518b983ff2be486e902bbd15135ae", + "reference": "eced5b5ce70518b983ff2be486e902bbd15135ae", + "shasum": "" + }, + "require": { + "brick/math": "^0.10|^0.11|^0.12|^0.13", + "ext-mbstring": "*", + "php": ">=8.1" + }, + "require-dev": { + "ekino/phpstan-banned-code": "^1.0|^2.0|^3.0", + "ext-gmp": "*", + "ext-openssl": "*", + "infection/infection": "^0.28|^0.29", + "php-parallel-lint/php-parallel-lint": "^1.3", + "phpstan/extension-installer": "^1.3|^2.0", + "phpstan/phpstan": "^1.8|^2.0", + "phpstan/phpstan-deprecation-rules": "^1.0|^2.0", + "phpstan/phpstan-phpunit": "^1.1|^2.0", + "phpstan/phpstan-strict-rules": "^1.3|^2.0", + "phpunit/phpunit": "^10.1|^11.0|^12.0", + "rector/rector": "^1.0|^2.0", + "roave/security-advisories": "dev-latest", + "symfony/string": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0", + "symplify/easy-coding-standard": "^12.0" + }, + "suggest": { + "ext-bcmath": "For better performance (or GMP)", + "ext-gmp": "For better performance (or BCMath)", + "ext-openssl": "For OpenSSL based cyphering" + }, + "type": "library", + "autoload": { + "psr-4": { + "SpomkyLabs\\Pki\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Joni Eskelinen", + "email": "jonieske@gmail.com", + "role": "Original developer" + }, + { + "name": "Florent Morselli", + "email": "florent.morselli@spomky-labs.com", + "role": "Spomky-Labs PKI Framework developer" + } + ], + "description": "A PHP framework for managing Public Key Infrastructures. It comprises X.509 public key certificates, attribute certificates, certification requests and certification path validation.", + "homepage": "https://github.com/spomky-labs/pki-framework", + "keywords": [ + "DER", + "Private Key", + "ac", + "algorithm identifier", + "asn.1", + "asn1", + "attribute certificate", + "certificate", + "certification request", + "cryptography", + "csr", + "decrypt", + "ec", + "encrypt", + "pem", + "pkcs", + "public key", + "rsa", + "sign", + "signature", + "verify", + "x.509", + "x.690", + "x509", + "x690" + ], + "support": { + "issues": "https://github.com/Spomky-Labs/pki-framework/issues", + "source": "https://github.com/Spomky-Labs/pki-framework/tree/1.3.0" + }, + "funding": [ + { + "url": "https://github.com/Spomky", + "type": "github" + }, + { + "url": "https://www.patreon.com/FlorentMorselli", + "type": "patreon" + } + ], + "time": "2025-06-13T08:35:04+00:00" + }, { "name": "stof/doctrine-extensions-bundle", "version": "v1.14.0", @@ -6116,16 +6599,16 @@ }, { "name": "symfony/http-client", - "version": "v7.3.0", + "version": "v7.3.1", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "57e4fb86314015a695a750ace358d07a7e37b8a9" + "reference": "4403d87a2c16f33345dca93407a8714ee8c05a64" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/57e4fb86314015a695a750ace358d07a7e37b8a9", - "reference": "57e4fb86314015a695a750ace358d07a7e37b8a9", + "url": "https://api.github.com/repos/symfony/http-client/zipball/4403d87a2c16f33345dca93407a8714ee8c05a64", + "reference": "4403d87a2c16f33345dca93407a8714ee8c05a64", "shasum": "" }, "require": { @@ -6137,6 +6620,7 @@ }, "conflict": { "amphp/amp": "<2.5", + "amphp/socket": "<1.1", "php-http/discovery": "<1.15", "symfony/http-foundation": "<6.4" }, @@ -6149,7 +6633,6 @@ "require-dev": { "amphp/http-client": "^4.2.1|^5.0", "amphp/http-tunnel": "^1.0|^2.0", - "amphp/socket": "^1.1", "guzzlehttp/promises": "^1.4|^2.0", "nyholm/psr7": "^1.0", "php-http/httplug": "^1.0|^2.0", @@ -6191,7 +6674,7 @@ "http" ], "support": { - "source": "https://github.com/symfony/http-client/tree/v7.3.0" + "source": "https://github.com/symfony/http-client/tree/v7.3.1" }, "funding": [ { @@ -6207,7 +6690,7 @@ "type": "tidelift" } ], - "time": "2025-05-02T08:23:16+00:00" + "time": "2025-06-28T07:58:39+00:00" }, { "name": "symfony/http-client-contracts", @@ -10514,6 +10997,96 @@ ], "time": "2025-05-03T07:21:55+00:00" }, + { + "name": "web-token/jwt-library", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/web-token/jwt-library.git", + "reference": "650108fa2cdd6cbaaead0dc0ab5302e178b23b0a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/web-token/jwt-library/zipball/650108fa2cdd6cbaaead0dc0ab5302e178b23b0a", + "reference": "650108fa2cdd6cbaaead0dc0ab5302e178b23b0a", + "shasum": "" + }, + "require": { + "brick/math": "^0.12 || ^0.13", + "ext-json": "*", + "php": ">=8.2", + "psr/clock": "^1.0", + "spomky-labs/pki-framework": "^1.2.1" + }, + "conflict": { + "spomky-labs/jose": "*" + }, + "suggest": { + "ext-bcmath": "GMP or BCMath is highly recommended to improve the library performance", + "ext-gmp": "GMP or BCMath is highly recommended to improve the library performance", + "ext-openssl": "For key management (creation, optimization, etc.) and some algorithms (AES, RSA, ECDSA, etc.)", + "ext-sodium": "Sodium is required for OKP key creation, EdDSA signature algorithm and ECDH-ES key encryption with OKP keys", + "paragonie/sodium_compat": "Sodium is required for OKP key creation, EdDSA signature algorithm and ECDH-ES key encryption with OKP keys", + "spomky-labs/aes-key-wrap": "For all Key Wrapping algorithms (AxxxKW, AxxxGCMKW, PBES2-HSxxx+AyyyKW...)", + "symfony/console": "Needed to use console commands", + "symfony/http-client": "To enable JKU/X5U support." + }, + "type": "library", + "autoload": { + "psr-4": { + "Jose\\Component\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Florent Morselli", + "homepage": "https://github.com/Spomky" + }, + { + "name": "All contributors", + "homepage": "https://github.com/web-token/jwt-framework/contributors" + } + ], + "description": "JWT library", + "homepage": "https://github.com/web-token", + "keywords": [ + "JOSE", + "JWE", + "JWK", + "JWKSet", + "JWS", + "Jot", + "RFC7515", + "RFC7516", + "RFC7517", + "RFC7518", + "RFC7519", + "RFC7520", + "bundle", + "jwa", + "jwt", + "symfony" + ], + "support": { + "issues": "https://github.com/web-token/jwt-library/issues", + "source": "https://github.com/web-token/jwt-library/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/Spomky", + "type": "github" + }, + { + "url": "https://www.patreon.com/FlorentMorselli", + "type": "patreon" + } + ], + "time": "2025-03-12T11:25:35+00:00" + }, { "name": "webmozart/assert", "version": "1.11.0", diff --git a/config/bundles.php b/config/bundles.php index 92ba5e0..b79badb 100644 --- a/config/bundles.php +++ b/config/bundles.php @@ -21,4 +21,5 @@ return [ Stof\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle::class => ['all' => true], Symfony\UX\Autocomplete\AutocompleteBundle::class => ['all' => true], SymfonyCasts\Bundle\ResetPassword\SymfonyCastsResetPasswordBundle::class => ['all' => true], + Drenso\OidcBundle\DrensoOidcBundle::class => ['all' => true], ]; diff --git a/config/packages/drenso_oidc.yaml b/config/packages/drenso_oidc.yaml new file mode 100644 index 0000000..2177a7a --- /dev/null +++ b/config/packages/drenso_oidc.yaml @@ -0,0 +1,19 @@ +drenso_oidc: + #default_client: default # The default client, will be aliased to OidcClientInterface + clients: + default: # The client name, each client will be aliased to its name (for example, $defaultOidcClient) + # Required OIDC client configuration + well_known_url: '%env(OIDC_WELL_KNOWN_URL)%' + client_id: '%env(OIDC_CLIENT_ID)%' + client_secret: '%env(OIDC_CLIENT_SECRET)%' + redirect_route: '/login/oidc/auth' + + # Extra configuration options + #redirect_route: '/login_check' + #custom_client_headers: [] + + # Add any extra client + #link: # Will be accessible using $linkOidcClient + #well_known_url: '%env(LINK_WELL_KNOWN_URL)%' + #client_id: '%env(LINK_CLIENT_ID)%' + #client_secret: '%env(LINK_CLIENT_SECRET)%' diff --git a/config/packages/security.yaml b/config/packages/security.yaml index 1382856..e1a28c6 100644 --- a/config/packages/security.yaml +++ b/config/packages/security.yaml @@ -10,6 +10,9 @@ security: class: App\User\Framework\Entity\User property: email + app_oidc: + id: App\User\Framework\Security\OidcUserProvider + app_ldap: id: App\User\Framework\Security\LdapUserProvider @@ -18,14 +21,12 @@ security: pattern: ^/(_(profiler|wdt)|css|images|js)/ security: false main: - lazy: true - provider: app_local - form_login: - login_path: app_login - check_path: app_login - enable_csrf: true logout: - path: app_logout + path: /logout + provider: app_oidc + oidc: + login_path: '/login/oidc' + check_path: '/login/oidc/auth' # activate different ways to authenticate # https://symfony.com/doc/current/security.html#the-firewall diff --git a/src/User/Framework/Controller/Web/LoginController.php b/src/User/Framework/Controller/Web/LoginController.php index 17d5b89..0f0dbf6 100644 --- a/src/User/Framework/Controller/Web/LoginController.php +++ b/src/User/Framework/Controller/Web/LoginController.php @@ -3,10 +3,17 @@ namespace App\User\Framework\Controller\Web; use App\User\Framework\Repository\UserRepository; +use App\User\Framework\Security\OidcUserProvider; use Doctrine\Common\Collections\ArrayCollection; +use Drenso\OidcBundle\Exception\OidcException; +use Drenso\OidcBundle\OidcClientInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use Symfony\Bundle\SecurityBundle\Security; +use Symfony\Component\HttpFoundation\RedirectResponse; +use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; +use Symfony\Component\Security\Http\Attribute\IsGranted; use Symfony\Component\Security\Http\Authentication\AuthenticationUtils; class LoginController extends AbstractController @@ -31,7 +38,7 @@ class LoginController extends AbstractController } #[Route(path: '/logout', name: 'app_logout')] - public function logout(): void + public function logout(Security $security, Request $request): void { throw new \LogicException('This method can be blank - it will be intercepted by the logout key on your firewall.'); } diff --git a/src/User/Framework/Controller/Web/LoginOidcController.php b/src/User/Framework/Controller/Web/LoginOidcController.php new file mode 100644 index 0000000..51e447b --- /dev/null +++ b/src/User/Framework/Controller/Web/LoginOidcController.php @@ -0,0 +1,32 @@ +generateAuthorizationRedirect(); + } + + #[Route('/login/oidc/auth', name: 'app_login_oidc_auth')] + public function oidcAuthenticate(): RedirectResponse + { + throw new \LogicException('This method can be blank - it will be intercepted by the "oidc" key on your firewall.'); + } + + #[Route('/logout/oidc', 'app_logout_oidc')] + public function oidcLogout(OidcClientInterface $oidcClient, Request $request, Security $security): RedirectResponse + { + // ToDo: Configure multiple authentication methods and redirect to the form login here + } +} diff --git a/src/User/Framework/Security/OidcUserProvider.php b/src/User/Framework/Security/OidcUserProvider.php new file mode 100644 index 0000000..b46557b --- /dev/null +++ b/src/User/Framework/Security/OidcUserProvider.php @@ -0,0 +1,55 @@ +userRepository->findOneBy(['email' => $userIdentifier]); + + if (null === $user) { + $user = new User() + ->setEmail($userData->getEmail()) + ->setName($userData->getFullName()) + ; + $this->userRepository->getEntityManager()->persist($user); + $this->userRepository->getEntityManager()->flush(); + } + } + + public function loadOidcUser(string $userIdentifier): UserInterface + { + return $this->userRepository->findOneBy(['email' => $userIdentifier]); + } + + public function refreshUser(UserInterface $user): UserInterface + { + return $this->userRepository->findOneBy(['email' => $user->getUserIdentifier()]); + } + + public function supportsClass(string $class): bool + { + return User::class === $class || OidcUser::class === $class; + } + + public function loadUserByIdentifier(string $identifier): UserInterface + { + return $this->userRepository->findOneBy(['email' => $identifier]); + } +} diff --git a/symfony.lock b/symfony.lock index f116441..efb410a 100644 --- a/symfony.lock +++ b/symfony.lock @@ -50,6 +50,18 @@ "migrations/.gitignore" ] }, + "drenso/symfony-oidc-bundle": { + "version": "4.2", + "recipe": { + "repo": "github.com/symfony/recipes-contrib", + "branch": "main", + "version": "2.0", + "ref": "e2b975158d940a191f48e3ff2c59108a1d7225e6" + }, + "files": [ + "config/packages/drenso_oidc.yaml" + ] + }, "php-http/discovery": { "version": "1.20", "recipe": {