diff --git a/composer.json b/composer.json index 33ffde89..b515cc4a 100644 --- a/composer.json +++ b/composer.json @@ -22,6 +22,7 @@ "florianv/swap": "^4.0", "florianv/swap-bundle": "dev-master", "gregwar/captcha-bundle": "^2.1.0", + "hslavich/oneloginsaml-bundle": "^2.10", "jbtronics/2fa-webauthn": "^1.0.0", "league/html-to-markdown": "^5.0.1", "liip/imagine-bundle": "^2.2", diff --git a/composer.lock b/composer.lock index e1c56d37..07998b71 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": "3a1c7d677a101ae6256c68bf69919414", + "content-hash": "73b35aff40231c2fe1ebf72c1d098689", "packages": [ { "name": "beberlei/assert", @@ -2365,6 +2365,67 @@ }, "time": "2022-01-11T08:28:06+00:00" }, + { + "name": "hslavich/oneloginsaml-bundle", + "version": "v2.10.0", + "source": { + "type": "git", + "url": "https://github.com/hslavich/OneloginSamlBundle.git", + "reference": "aee3450bd36b750a2e61b4a0ca19a09ecab7a086" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hslavich/OneloginSamlBundle/zipball/aee3450bd36b750a2e61b4a0ca19a09ecab7a086", + "reference": "aee3450bd36b750a2e61b4a0ca19a09ecab7a086", + "shasum": "" + }, + "require": { + "onelogin/php-saml": "^3.0", + "symfony/dependency-injection": "^5.4", + "symfony/deprecation-contracts": "^2.1 | ^3", + "symfony/event-dispatcher-contracts": "^2.4", + "symfony/framework-bundle": "^5.4", + "symfony/security-bundle": "^5.4" + }, + "require-dev": { + "dms/phpunit-arraysubset-asserts": "^0.2.0", + "doctrine/orm": "~2.3", + "php-coveralls/php-coveralls": "^2.2", + "phpunit/phpunit": "^9.0", + "symfony/event-dispatcher": "^5.4", + "symfony/phpunit-bridge": "^5.4" + }, + "type": "symfony-bundle", + "autoload": { + "psr-4": { + "Hslavich\\OneloginSamlBundle\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "hslavich", + "email": "hernan.slavich@gmail.com" + } + ], + "description": "OneLogin SAML Bundle for Symfony", + "keywords": [ + "SSO", + "onelogin", + "saml" + ], + "support": { + "issues": "https://github.com/hslavich/OneloginSamlBundle/issues", + "source": "https://github.com/hslavich/OneloginSamlBundle/tree/v2.10.0" + }, + "time": "2022-11-23T17:12:47+00:00" + }, { "name": "imagine/imagine", "version": "1.3.3", @@ -3767,6 +3828,61 @@ }, "time": "2021-06-29T08:12:37+00:00" }, + { + "name": "onelogin/php-saml", + "version": "3.6.1", + "source": { + "type": "git", + "url": "https://github.com/onelogin/php-saml.git", + "reference": "a7328b11887660ad248ea10952dd67a5aa73ba3b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/onelogin/php-saml/zipball/a7328b11887660ad248ea10952dd67a5aa73ba3b", + "reference": "a7328b11887660ad248ea10952dd67a5aa73ba3b", + "shasum": "" + }, + "require": { + "php": ">=5.4", + "robrichards/xmlseclibs": ">=3.1.1" + }, + "require-dev": { + "pdepend/pdepend": "^2.5.0", + "php-coveralls/php-coveralls": "^1.0.2 || ^2.0", + "phploc/phploc": "^2.1 || ^3.0 || ^4.0", + "phpunit/phpunit": "<7.5.18", + "sebastian/phpcpd": "^2.0 || ^3.0 || ^4.0", + "squizlabs/php_codesniffer": "^3.1.1" + }, + "suggest": { + "ext-curl": "Install curl lib to be able to use the IdPMetadataParser for parsing remote XMLs", + "ext-gettext": "Install gettext and php5-gettext libs to handle translations", + "ext-openssl": "Install openssl lib in order to handle with x509 certs (require to support sign and encryption)" + }, + "type": "library", + "autoload": { + "psr-4": { + "OneLogin\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "OneLogin PHP SAML Toolkit", + "homepage": "https://developers.onelogin.com/saml/php", + "keywords": [ + "SAML2", + "onelogin", + "saml" + ], + "support": { + "email": "sixto.garcia@onelogin.com", + "issues": "https://github.com/onelogin/php-saml/issues", + "source": "https://github.com/onelogin/php-saml/" + }, + "time": "2021-03-02T10:13:07+00:00" + }, { "name": "paragonie/constant_time_encoding", "version": "v2.6.3", @@ -5213,6 +5329,48 @@ ], "time": "2021-09-25T23:10:38+00:00" }, + { + "name": "robrichards/xmlseclibs", + "version": "3.1.1", + "source": { + "type": "git", + "url": "https://github.com/robrichards/xmlseclibs.git", + "reference": "f8f19e58f26cdb42c54b214ff8a820760292f8df" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/robrichards/xmlseclibs/zipball/f8f19e58f26cdb42c54b214ff8a820760292f8df", + "reference": "f8f19e58f26cdb42c54b214ff8a820760292f8df", + "shasum": "" + }, + "require": { + "ext-openssl": "*", + "php": ">= 5.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "RobRichards\\XMLSecLibs\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "A PHP library for XML Security", + "homepage": "https://github.com/robrichards/xmlseclibs", + "keywords": [ + "security", + "signature", + "xml", + "xmldsig" + ], + "support": { + "issues": "https://github.com/robrichards/xmlseclibs/issues", + "source": "https://github.com/robrichards/xmlseclibs/tree/3.1.1" + }, + "time": "2020-09-05T13:00:25+00:00" + }, { "name": "s9e/regexp-builder", "version": "1.4.6", diff --git a/config/bundles.php b/config/bundles.php index 8ca67ae7..91ddea04 100644 --- a/config/bundles.php +++ b/config/bundles.php @@ -27,4 +27,5 @@ return [ Scheb\TwoFactorBundle\SchebTwoFactorBundle::class => ['all' => true], SpomkyLabs\CborBundle\SpomkyLabsCborBundle::class => ['all' => true], Webauthn\Bundle\WebauthnBundle::class => ['all' => true], + Hslavich\OneloginSamlBundle\HslavichOneloginSamlBundle::class => ['all' => true], ]; diff --git a/config/packages/hslavich_onelogin_saml.yaml b/config/packages/hslavich_onelogin_saml.yaml new file mode 100644 index 00000000..de3882ab --- /dev/null +++ b/config/packages/hslavich_onelogin_saml.yaml @@ -0,0 +1,57 @@ +hslavich_onelogin_saml: + # Basic settings + idp: + entityId: 'http://localhost:8080/realms/master' + singleSignOnService: + url: 'http://localhost:8080/realms/master/protocol/saml' + binding: 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect' + singleLogoutService: + url: 'http://localhost:8080/realms/master/protocol/saml' + binding: 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect' + x509cert: 'MIICmzCCAYMCBgGGcG8PJTANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZtYXN0ZXIwHhcNMjMwMjIwMjAwNDMyWhcNMzMwMjIwMjAwNjEyWjARMQ8wDQYDVQQDDAZtYXN0ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDQAle3ob0ary+Hq+mr2IvGueJicIxNqGeG/eV+NpoHUVggHSdb+9kudy+Os0xhAtz8nffTc8T5PK09GClXy7O5mAg8X9E5p0YeRZOxqgBXXVEtgPXaliD2N2mVrY/Ju2uLNAtrwWdBfnLBZuPZLD26TzOX/Q4u39SbhoA395S/iPwmxM00xDtrnXFGc2RYTgoTuLWFF6uioAmzxZSdIphLPiPwDMs5KCypW+lTOn8pztdAhAylXqiG7yFhReP7oEyb8IcNlUulJaloIfTWyLuQI1fEXA2gdkRULiOuxjGM3Wt2I6OOnZVzT7/+3/h7HVF4EI/xDpET6hQw7YszDr39AgMBAAEwDQYJKoZIhvcNAQELBQADggEBACaRkpf12OxGpdrsfsR5uslWl3GPA7HaKFHkRN3+0owf4j61rRJdxpkNmFKLGEZGAn3F+IBVzXIOx+mOq71BLKj/hxJ82bYJeUtK0a/fsX3S7z8TMXMgzzIQXS+XE4X7E8M3JEF+OKSuwG6bcaPJR8xscQ7i6z0rW14P1QgoEFAA6xhoHxK/AH2CTH/f8ojc2F5pPaYQJkuznd0OfcLAhPwMJ8btKGq9rNV/1EI59V+srA9lHvSWPfg6jXPsX96PSjTGljuHbZGMIka2mz4YOUvn9jlCGgv+gruIxeq8VKKPxfmDlSs9Jeof93MtYY92s4dDaJOru04mlqyKeFBic6o=' + sp: + entityId: 'http://localhost:8000/saml/metadata' + assertionConsumerService: + url: 'http://localhost:8000/saml/acs' + binding: 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST' + singleLogoutService: + url: 'http://localhost:8000/saml/logout' + binding: 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect' + x509cert: 'MIICmzCCAYMCBgGGcIfLmDANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZwYXJ0ZGIwHhcNMjMwMjIwMjAzMTMzWhcNMzMwMjIwMjAzMzEzWjARMQ8wDQYDVQQDDAZwYXJ0ZGIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCmz9Lr8PxVjqqhGjjH4FbhVDbEPIplcQ1cFhTKu1NYpwHIm01pNnEwiyoLMBrZ16qq0PvCX+KCIjuJbC44k6N/+UCjbSZ8Fu+vyT9OkKVLvimc5sg9m9Kys+WiuaxzSEa2dA88khyGb6O9huuVYjibjROAN5I20h8f0FLfvolqWfEXVM00LIYYCHcvKNGq6PH0SS+2P6CGHoRrEFOoi7v7kkL6gWqYzPA/T7GSb78W14gU6FKcvQXPYOdsL7dYDy634BCd9k/tNF6JkiFi9U1IP8LEYkQUq3mKGRSjoPKKztws00ol3Nfd04XAdPKxIb3ff3io0vONE3QfJsgTzdR7AgMBAAEwDQYJKoZIhvcNAQELBQADggEBAEkYH4pCKxqoABjYGRml+ea5nteF/qsff6qHcNU8Unw1XLZO7ES1GU4Ij3RSFdt1SoKnphXnBtlVIechkOnOaECGs4RdbG4RGSFfusiEcWHbp1C0n3cnaUoV0/PJ3iETeeaPduqz9I/dlwhOxEOkpCaomYm4j2hfNcI9pmdM8bZuG+6dedh02ILrufQiCREmF6Sp+AOjueoFOoGwsXMbTuKo9pNizCO2OTT6nrjbNhjzoIvzbmlqiOGFs7YmpyTHcyqm66ACOnu1Nq9z9QLGkhvwjAmEytp6A9yEEkl0QO+DVhlAnvfdSMaR9jgyGtnBXQGOHv4osPtCtrk3IU4nB3s=' + privateKey: 'MIIEogIBAAKCAQEAps/S6/D8VY6qoRo4x+BW4VQ2xDyKZXENXBYUyrtTWKcByJtNaTZxMIsqCzAa2deqqtD7wl/igiI7iWwuOJOjf/lAo20mfBbvr8k/TpClS74pnObIPZvSsrPlormsc0hGtnQPPJIchm+jvYbrlWI4m40TgDeSNtIfH9BS376JalnxF1TNNCyGGAh3LyjRqujx9Ekvtj+ghh6EaxBTqIu7+5JC+oFqmMzwP0+xkm+/FteIFOhSnL0Fz2DnbC+3WA8ut+AQnfZP7TReiZIhYvVNSD/CxGJEFKt5ihkUo6Dyis7cLNNKJdzX3dOFwHTysSG93394qNLzjRN0HybIE83UewIDAQABAoIBAA1M7dLtPJlvzjAZQKTDQPondlRwRVKwUHHiutatWAhuDIjbxTDZ6+2Ecx5AQCvVc+C52BEYBx38L8YVz5uoPfWiwKInPlXPmF3qTHdtthhTecruZdHvvj2MdYdjiZoJjcXXfC2GsuqPNT2T5+3Zzoysk3z6MVjYqS2mtSzs6tUFZOY13/zMnrELjR2dFrigndjQgb5vENJ+/WNH4k9rt7KGDaMniJWHi3bDDNwilR0XrwhJVav0PIl7h8bMk95ixqo5B+RN0EMhfS+j3+8QJhYbGzXIyJbgMGTUGb23tBIDl6RFblLoic/PEVpA5yhVbLtdoMy5Mn+Y28yZPh6/VB0CgYEA1xtwZVbrRObv76bIkqgCXEYbiXhbFHzGTaI23UEBrV60VNr5LZl/vqA6JowDFUYl30Ytzr7TvC5KwfrNhaYOqVd4rMg145cn8J61bRHArMaXouVYVwWKEni50gCktVy8Tt2Nbzfja2rccCqv3JM2HHp49+e9CLi/D95XPAip3vcCgYEAxoYB7/OQmGMHnqwz2CUnLhGcnC1X4fZ+EJuRo1BXRcntCS4lwXCoyC3Es+YLZ6tfhUp17i/HaT3tJyp6F+EM43zIxwyDVCl6t0yFkjLHRdZHR3xGMMfcMLZGRY99Y25QyW1/GJFKff7D+rKvrpBVcl+9xLYcpIN6ULuHqs9f4Z0CgYBrDL2/wSTusltAEemJitE56K31mQ8CwCHUKuFQ9PQHurTV8e/F8LkxPf4ShuVV5gYc+oj7dd5brVII/W7gj0aGogBtRGoFLIl05xb1A7u2gFKgf7CaBiizjp8zUpyloVQZj4q+ibrFD3ZK4AOLKzvnqk+fWBWsTHzRQd56Avm++wKBgF3eR1Q6CojDanrwWaM+DgSOd0qxdfh2IK2hoX9jIaDyFY5dr6SDrIraeUPG5mWidowD5Tc2iEeO7G+0ef6IfxuhiR31ILPO2SOKny29rNOsug9nB5lRJyAxT5DchCFbq/9SMuJe8KYarHgBvWgA/yYRdx1oLqrrMA60XTW60E9RAoGALmoMX1CLe7BBrqaZrHBAqkV/6koTPSMuYVUZpbKgTmA7VsBScUZaX8huS7ARjLfoujxcNuFT4haPlY7gybvhEN0dMlqRwVNeiD3jo+PdDxu3h9SM6GTuVks1XWoifHBRj2NngBEipV3WDXLJR2sAbUArUdL58y12f7EWFdX41+s=' + # Optional settings + #baseurl: 'http://myapp.com' + #strict: true + debug: true + security: + allowRepeatAttributeName: true + # nameIdEncrypted: false + authnRequestsSigned: true + logoutRequestSigned: true + # logoutResponseSigned: false + # wantMessagesSigned: false + # wantAssertionsSigned: true + # wantNameIdEncrypted: false + # requestedAuthnContext: true + # signMetadata: false + # wantXMLValidation: true + # relaxDestinationValidation: false + # destinationStrictlyMatches: true + # rejectUnsolicitedResponsesWithInResponseTo: false + # signatureAlgorithm: 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256' + # digestAlgorithm: 'http://www.w3.org/2001/04/xmlenc#sha256' + #contactPerson: + # technical: + # givenName: 'Tech User' + # emailAddress: 'techuser@example.com' + # support: + # givenName: 'Support User' + # emailAddress: 'supportuser@example.com' + # administrative: + # givenName: 'Administrative User' + # emailAddress: 'administrativeuser@example.com' + #organization: + # en: + # name: 'Example' + # displayname: 'Example' + # url: 'http://example.com' \ No newline at end of file diff --git a/config/packages/security.yaml b/config/packages/security.yaml index e58ab1ec..0e3b5c88 100644 --- a/config/packages/security.yaml +++ b/config/packages/security.yaml @@ -6,12 +6,22 @@ security: # https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers providers: - # used to reload user from session & other features (e.g. switch_user) - app_user_provider: + local_users: entity: class: App\Entity\UserSystem\User property: name + saml_users: + saml: + user_class: App\Entity\UserSystem\User + default_roles: [ 'ROLE_USER' ] + + # used to reload user from session & other features (e.g. switch_user) + app_user_provider: + chain: + providers: ['local_users', 'saml_users'] + + firewalls: dev: pattern: ^/(_(profiler|wdt)|css|images|js)/ @@ -20,6 +30,7 @@ security: provider: app_user_provider lazy: true user_checker: App\Security\UserChecker + entry_point: form_login two_factor: auth_form_path: 2fa_login @@ -29,6 +40,13 @@ security: login_throttling: max_attempts: 5 # per minute + saml: + #username_attribute: username + #use_attribute_friendly_name: false + check_path: saml_acs + login_path: saml_login + failure_path: saml_login + # https://symfony.com/doc/current/security/form_login_setup.html form_login: login_path: login diff --git a/config/routes/hslavich_saml.yaml b/config/routes/hslavich_saml.yaml new file mode 100644 index 00000000..bbba3429 --- /dev/null +++ b/config/routes/hslavich_saml.yaml @@ -0,0 +1,2 @@ +hslavich_saml_sp: + resource: "@HslavichOneloginSamlBundle/Resources/config/routing.yml" \ No newline at end of file diff --git a/symfony.lock b/symfony.lock index d453ff2e..a4bb23ff 100644 --- a/symfony.lock +++ b/symfony.lock @@ -173,6 +173,9 @@ "gregwar/captcha-bundle": { "version": "v2.0.6" }, + "hslavich/oneloginsaml-bundle": { + "version": "v2.10.0" + }, "imagine/imagine": { "version": "1.2.2" }, diff --git a/templates/security/login.html.twig b/templates/security/login.html.twig index 44d98397..1dd6c52a 100644 --- a/templates/security/login.html.twig +++ b/templates/security/login.html.twig @@ -27,6 +27,8 @@ + SAML Login +