otevrenamesta / simplesamlphp-saml2-eidas
围绕simplesamlphp/saml2的PHP库,为eIDAS相关集成提供辅助工具
v1.0
2019-12-02 15:56 UTC
Requires
- php: >=7.2
- ext-dom: *
- ext-openssl: *
- ext-zlib: *
- simplesamlphp/saml2: ^4.1
Requires (Dev)
- mockery/mockery: ^1.3
- phpunit/phpunit: ^8.4
- sensiolabs/security-checker: ^6.0
This package is auto-updated.
Last update: 2024-09-11 00:35:16 UTC
README
关于
这个库旨在简化需要eIDAS SAML集成的PHP应用程序的开发,特别是基于基于simplesamlphp/saml2库的用户身份验证,该库是SimpleSAMLphp项目的基础,但对于通常的应用程序来说过于庞大,难以集成
要求
- PHP >= 7.2(这是由底层的simplesamlphp/saml2库提供的)
- PHP扩展DOM、Zlib、OpenSSL
用法
- (1) 了解底层库 simplesamlphp/saml2
- (2) 使用composer安装库
composer require otevrenamesta/simplesamlphp-saml2-eidas
- (3) 实现你的容器(重要方法包括
generateId
以及根据你的环境,文件存储方法和日志接口)
// sample generic container implementation use SAML2\Compat\AbstractContainer; use Psr\Log\LoggerInterface; use Psr\Log\Test\TestLogger; class CustomContainerInterface extends AbstractContainer { public function getLogger(): LoggerInterface { return new TestLogger(); } public function generateId(): string { return uniqid('_'); } public function debugMessage($message, string $type): void { $this->getLogger()->debug($message, [$type]); } public function redirect(string $url, array $data = []): void { // provide your own redirect method with GET QUERY data } public function postRedirect(string $url, array $data = []): void { // provide your own code to do redirect with POST data } public function getTempDir(): string { // very simple solution return sys_get_temp_dir(); } public function writeFile(string $filename, string $data, int $mode = null): void { // put contents into file in temporary directory $file = tempnam($this->getTempDir(), $filename); $handle = fopen($file, $mode === null ? 0600 : $mode); fwrite($handle, $data); fclose($handle); } }
- (4.a) 使用此库创建带有eIDAS RequestedAttributes和SPType的签名AuthRequest
use OMSAML2\OMSAML2; use OMSAML2\SamlpExtensions; use SAML2\Constants; OMSAML2::setOwnPrivateKeyData("-----BEGIN RSA PRIVATE KEY----- pem key data -----END RSA PRIVATE KEY-----"); OMSAML2::setOwnCertificatePublicKey("-----BEGIN CERTIFICATE----- pem certificate data -----END CERTIFICATE-----"); OMSAML2::setIdPMetadataUrl("https://tnia.eidentita.cz/FPSTS/FederationMetadata/2007-06/FederationMetadata.xml"); $request = OMSAML2::generateAuthRequest( new CustomContainerInterface(), 'https://sep.example.com', // SeP issuer value 'https://sep.example.com/assertion_consumer_service', // SeP ACS URL, url to redirect user after authentication OMSAML2::extractSSOLoginUrls()[Constants::BINDING_HTTP_REDIRECT], // retrieve SSO redirect url from IdP metadata OMSAML2::LOA_LOW, // require minimal level-of-assurance (LoA), ie. authentication methods, that do not guarantee user identity exists in real world 'minimum' ); // create eIDAS samlp:Extensions with $extensions = new SamlpExtensions(); // single RequestedAttribute Name="email" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="false" without AttributeValue $extensions->addRequestedAttributeParams('email'); // single RequestedAttribute Name="http://www.stork.gov.eu/1.0/age" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true" without AttributeValue $extensions->addRequestedAttributeParams('http://www.stork.gov.eu/1.0/age', 'urn:oasis:names:tc:SAML:2.0:attrname-format:uri', true); // you do not have to do this, public is default type of SeP within this library, allowed values are 'public' or 'private' $extensions->setSPType('public'); // sign the samlp:AuthnRequest using private key set in the beginning $request_signed = OMSAML2::signDocument($extensions->toXML($request->toUnsignedXML())); // generate final user redirect URL with embedded SAMLRequest containing signed AuthnRequest $sso_redirect_url = OMSAML2::getSSORedirectUrl($request_signed); // example result of this action is url like this: // https://tnia.eidentita.cz/FPSTS/saml2/basic?SAMLRequest=1ZhtU%2BI6FMff%2BymY%2BtKBtMhjR9gpIAgCYnm4ypud0KZtpE1qkkLx09%2B0PIjuenXv7s6uM844PT3n5JeTk39SLr7EgZ9ZIcYxJTVFy6nKl%2FrJBYeBH%2BpGJDxioscIcZGRfoTr6YuaEjGiU8gx1wkMENeFpY%2BNQV%2FP51Q9ZFRQi%2FrKUch%2FR0DOERMSQMl0WzXla9FGRW2hFh3t3NGUzGxPJ32lB%2BcR6hIuIBHSpGrVrJbPqvmJVtDVqvybK5mWBMYEijTKEyLkOgCCYJhD2EZEYAFz1hNoj8aTMUj48mAh2SwlY%2BxRmpTwKEBsjNgKW2hq9p8zcRTmUAyD0Ec5iwbgwP%2FV2kV95dswpZ6WUk%2BhWf2NBBfg2OnC5voYuxI%2FYmhXQ5tvR5ex6%2FU6tz7PUeaCvKqqQK0C6WNz7J4q9ZNMZh%2BO7C5xaJqtCQkl2II%2BfkprMkDCo3bG8F3KsPCCN3JrQFOT3FkUW1lLK5BTBSQjPI%2BRIn44m1rYk2YDytAp4zDLPZgvlrZ5k6wmchBDxEKZqdmtKaeveiGdzoRBwh3KAv7y8V2EF8VCZIV8GiI7y%2FczkRg%2FlvC7FboA3zK2sCtb8gcrJctweqjPc5YZ9CNUb%2BYr7aezZbfs%2Bi1RHZad3qyydorXnp8fmZFlDy7pw3DWEPOgUEuJjoNTw6HU28dXPXNY3m0EPveGdwGfmP60nS9fgvNZ%2BQ6dG2sKqA%2BqgIjBw6x7NkePTbhwy0HQWore7Ea4jnnFz9TxvAVjNS7dDx9KMXDd8rCjRVcjz5jdr%2BebASuu2pVLc1OMbNskXqft3JubsluZPWLA85vuVX45Lrhq0Mj742p7OLuf3Xi9cWU%2BabnmZn6vGcbYwuGN02CDXmkuunewMyPanagsL9kmnjTu7zyGmw21OhJMvbGK%2Fcb5w%2FXUfpoUr8Z24QY9hIulof0DkRaXOl7BNUrjzm2MjTh%2BKoTqukr60bRBysOGWer1wxbE4fVVxyFWMdaum6umNbn0V%2BSxbziV2%2FnqCfeM6Zq1W2zkUGqui41O17FKZ3HR8JaN6ePtZtSDLV65mlO3VjuU%2FqjWJy%2BN9Z0a74QY2aksS30SKBaZJg1CyDBPlC7ABAdRsBedY7%2BmL0VKrnh913FSByHPoYjRUIpiBPrUAD5d75Tou5Hbd29w7CEvY4FIotZ8p1zpQIdGfz1sEiQ3zz5Gkqce%2Bng02YTo%2F6UIo4WPrQtwnGmf95ldCIYXkUA%2Fx%2FltvsxQHm8vNjYXlC1zLl0lieQBC6CLlAzmSSxmyK4pDvS5NCWRbSkZULxzXMqxEmvWSZ31iOFEIH6CyKIREWzTpDaSuwgz4f05wNelh4eVAul%2BgH4o7wOUgGbEpHwJw7YZ4vzzALdhgP1NkuLzMHfwCpFPgtyC4s938Xe3GRpA7P9lTJgbLrqRHwC%2FnGuPdaDZnm5aZS%2FNr17szd9O45e3yCj9100%2FBRz8G%2Bb%2B4TXhloeCBPr4u0TejjGXN0GtBHbmDbB8iAMun0kULD4XsZAH8OfhFQwmBwrE9t%2FDvHmHOfQoQX%2B6MT6%2B%2B3xo%2FU6FflNH%2BOEO%2B3xNPZiOf%2Byon%2FwL¶m=2
- (4.b) 使用此库验证IdP元数据或SAMLResponse
use OMSAML2\OMSAML2; use SAML2\DOMDocumentFactory; use SAML2\Response; // validate SAMLResponse $responseData = base64_decode($_POST['SAMLResponse'], true); $response_dom = DOMDocumentFactory::fromString($responseData); $response = new Response($response_dom->documentElement); OMSAML2::validateSignature(OMSAML2::getPublicKeyFromCertificate("https://nia.otevrenamesta.cz/tnia.crt"), $response); // validate IdP Metadata signature by pinning certificate OMSAML2::setIdPMetadataUrl("https://tnia.eidentita.cz/FPSTS/FederationMetadata/2007-06/FederationMetadata.xml"); OMSAML2::validateSignature(OMSAML2::getPublicKeyFromCertificate("https://nia.otevrenamesta.cz/tnia.crt"));
还有更多,如果你需要灵感,请查看测试
免责声明
此库是在针对捷克共和国IdP NIA开发和测试的,可能与其他IdP或eIDAS节点不兼容
鸣谢
此库由Otevřená Města z.s.开发