simplesamlphp / openid
OpenID 工具库
dev-master
2024-09-19 11:24 UTC
Requires
- php: ^8.2
- guzzlehttp/guzzle: ^7.8
- psr/http-client: ^1
- psr/http-message: ^2
- psr/log: ^3
- psr/simple-cache: ^3
- web-token/jwt-library: ^3.4
Requires (Dev)
This package is auto-updated.
Last update: 2024-09-19 11:24:38 UTC
README
警告:此库正处于积极开发中,不应在生产环境中使用!
此库提供了一些在处理 OpenID 规范族时可能有用的通用工具。
安装
可以使用 Composer 安装此库
composer require simplesamlphp/openid
OpenID 联邦
库的初始功能围绕 OpenID 联邦规范。要使用它,请创建 \SimpleSAML\OpenID\Federation
类的一个实例
<?php declare(strict_types=1); namespace Your\Super\App; use SimpleSAML\OpenID\Algorithms\SignatureAlgorithmBag; use SimpleSAML\OpenID\Algorithms\SignatureAlgorithmEnum; use SimpleSAML\OpenID\SupportedAlgorithms; use Psr\SimpleCache\CacheInterface; use Psr\Log\LoggerInterface; use SimpleSAML\OpenID\Federation; use Symfony\Component\HttpFoundation\Response; class Test { public function __construct( protected CacheInterface $cache, protected LoggerInterface $logger, ) { } public function __invoke(): Response { // Instantiation example by using default options. // * 'RS256' as supported algorithm // * no caching support (not recommended for production environment) // * no logging support $federationTools = new Federation(); // Instantiation example by injecting some of the dependencies // Define the supported signature algorithms: $supportedAlgorithms = new SupportedAlgorithms( new SignatureAlgorithmBag( SignatureAlgorithmEnum::RS256, // ... if needed, add other supported signature algorithms here ) ); // Define the maximum cache TTL for federation artifacts. This will be used together with 'exp' // claim to resolve the maximum cache time for trust chains, entity statements, etc. $maxCacheDuration = new DateInterval('PT6H'); // Instantiate by injecting own options / dependencies: $federationTools = new Federation( supportedAlgorithms: $supportedAlgorithms, maxCacheDuration: $maxCacheDuration, cache: $this->cache, // \Psr\SimpleCache\CacheInterface logger: $this->logger, // \Psr\Log\LoggerInterface ); // Continue with using available tools ... return new Response(); } }
信任链解析器
一旦实例化了 \SimpleSAML\OpenID\Federation
,您就可以继续使用可用的工具。我们将首先查看的是信任链解析器工具。此工具可用于尝试解决给定叶实体(主题)和受信任锚点的(最短)信任链
// ... try { /** @var \SimpleSAML\OpenID\Federation $federationTools */ /** @var \SimpleSAML\OpenID\Federation\TrustChain $trustChain */ $trustChain = $federationTools->trustChainResolver()->for( 'https://leaf-entity-id.example.org/', // Trust chain subject (leaf entity). [ 'https://trust-achor-id.example.org/', // List of valid trust anchors. ], ); } catch (\Throwable $exception) { $this->loggerService->error('Could not resolve trust chain: ' . $exception->getMessage()) return; }
如果成功解决了信任链,这将返回一个 \SimpleSAML\OpenID\Federation\TrustChain
实例。否则,将抛出异常。
一旦您有了信任链,您可以尝试获取特定实体类型的解析元数据。解析元数据意味着所有中间的元数据策略都已成功应用。这里有一个尝试获取 OpenID RP 元数据的示例,它将返回一个数组(如果给定实体类型没有元数据则返回 null)
// ... $entityType = \SimpleSAML\OpenID\Codebooks\EntityTypesEnum::OpenIdRelyingParty; try { /** @var \SimpleSAML\OpenID\Federation\TrustChain $trustChain */ $metadata = $trustChain->getResolvedMetadata($entityType); } catch (\Throwable $exception) { $this->loggerService->error( sprintf( 'Error resolving metadata for entity type %s. Error: %s.', $entityType->value, $exception->getMessage(), ), ); return; } if (is_null($metadata)) { $this->loggerService->error( sprintf( 'No metadata available for entity type %s.', $entityType->value, ), ); return; }
如果获取元数据导致异常,则认为元数据无效,应予以丢弃。
签名附加验证
整个信任链(每个实体声明)已使用配置/从属声明中的 JWKS 声明的公钥进行验证。根据规范建议,您还可以使用您以某种安全方式获得的信任锚点公钥(JWKS)验证信任链配置声明的签名(这样在获取信任锚点配置声明时不仅依赖于 TLS 保护)
// ... // Get entity statement for the resolved Trust Anchor: /** @var \SimpleSAML\OpenID\Federation\TrustChain $trustChain */ $trustAnchorConfigurationStatement = $trustChain->getResolvedTrustAnchor(); // Get data that you need to prepare appropriate public keys, for example, the entity ID: $trustAnchorEntityId = $trustAnchorConfigurationStatement->getIssuer(); // Prepare JWKS array containing Trust Anchor public keys that you have acquired in secure out-of-band way ... /** @var array $trustAnchorJwks */ try { $trustAnchorConfigurationStatement->verifyWithKeySet($trustAnchorJwks); } catch (\Throwable $exception) { $this->loggerService->error('Could not verify trust anchor configuration statement signature: ' . $exception->getMessage()); return; }