thomasvargiu/php-openid-client

该包已被 废弃 并不再维护。作者建议使用 facile-it/php-openid-client 包代替。

OpenId 客户端

1.0.1 2019-07-22 14:05 UTC

This package is auto-updated.

Last update: 2020-04-09 13:15:13 UTC


README

完整的 OpenID 客户端实现。

Latest Stable Version Total Downloads License Code Coverage Build Status Scrutinizer Code Quality

库的大部分代码基于出色的 node-openid-client

实现的规范和功能

支持以下草案规范

安装

要求

  • psr/http-client-implementation 实现
  • psr/http-factory-implementation 实现
  • psr/http-message-implementation 实现
composer require thomasvargiu/php-openid-client

RSA 签名算法已从 JWT 框架包中包含。如果您需要其他算法,您应手动安装它。

基本用法

对于基本用法,您不需要任何其他依赖包。


use TMV\OpenIdClient\Client\Client;
use TMV\OpenIdClient\Issuer\IssuerFactory;
use TMV\OpenIdClient\Client\Metadata\ClientMetadata;
use TMV\OpenIdClient\Service\AuthorizationService;
use TMV\OpenIdClient\Service\UserinfoService;
use Psr\Http\Message\ServerRequestInterface;

$issuerFactory = new IssuerFactory();
$issuer = $issuerFactory->fromUri('https://example.com/.well-known/openid-configuration');

$clientMetadata = new ClientMetadata(
    'client_id', // client_id
    // other claims
    [
        'redirect_uris' => [
            'https://my-rp.com/callback',    
        ],
    ]
);

$client = new Client($issuer, $clientMetadata);


// Authorization

$authorizationService = new AuthorizationService();
$redirectAuthorizationUri = $authorizationService->getAuthorizationUri(
    $client,
    ['login_hint' => 'user_username'] // custom params
);
// you can use this uri to redirect the user


// Get access token

/** @var ServerRequestInterface::class $serverRequest */
$serverRequest = null; // get your server request
$callbackParams = $authorizationService->getCallbackParams($serverRequest, $client);
$tokenSet = $authorizationService->callback($client, $callbackParams);

$idToken = $tokenSet->getIdToken(); // Unencrypted id_token
$accessToken = $tokenSet->getAccessToken(); // Access token
$refreshToken = $tokenSet->getRefreshToken(); // Refresh token

$claims = $tokenSet->claims(); // IdToken claims (if id_token is available)


// Refresh token
$tokenSet = $authorizationService->refresh($client, $tokenSet->getRefreshToken());


// Get user info

$userinfoService = new UserinfoService();
$userinfo = $userinfoService->getUserInfo($client, $tokenSet);

依赖和复杂用法

某些类需要依赖。通常,它们在简单基本用法中自动实例化,但您可以在需要时注入它们。

PSR-17 HTTP 工厂自动发现。PSR-18 HTTP 客户端自动发现,但建议您始终注入您的客户端,特别是当发现提供者配置和 JWK 集和缓存结果时。

如果您需要其他算法,您应创建一个包含您的算法的 AlgorithmManager 并在需要时注入它。

创建完整的配置实例的示例 AuthorizationService

use Jose\Component\Core\AlgorithmManager;
use Jose\Component\Signature\Algorithm;
use Jose\Component\Encryption\Algorithm\KeyEncryption;
use Jose\Component\Encryption\Algorithm\ContentEncryption;
use Jose\Component\Signature\JWSVerifier;
use Jose\Component\Encryption\JWELoader;
use Jose\Component\Encryption\Serializer\CompactSerializer;
use Jose\Component\Encryption\Serializer\JWESerializerManager;
use Jose\Component\Encryption\JWEDecrypter;
use Jose\Component\Encryption\Compression\CompressionMethodManager;
use Jose\Component\Encryption\Compression\Deflate;
use TMV\OpenIdClient\Token\IdTokenVerifier;
use TMV\OpenIdClient\Token\TokenSetVerifier;
use TMV\OpenIdClient\Token\TokenSetFactory;
use TMV\OpenIdClient\Token\TokenDecrypter;
use TMV\OpenIdClient\Token\ResponseTokenVerifier;
use TMV\OpenIdClient\Service\AuthorizationService;

$algorithmManager = new AlgorithmManager([
    new Algorithm\None(),
    new Algorithm\RS256(),
    new KeyEncryption\RSAOAEP(),
    new ContentEncryption\A256CBCHS512(),
]);

$JWSVerifier = new JWSVerifier($algorithmManager);
$idTokenVerifier = new IdTokenVerifier($JWSVerifier);
$tokenSetVerifier = new TokenSetVerifier($idTokenVerifier);
$responseTokenVerifier = new ResponseTokenVerifier($JWSVerifier);
$JWELoader = new JWELoader(
    new JWESerializerManager([new CompactSerializer()]),
    new JWEDecrypter($algorithmManager, $algorithmManager, new CompressionMethodManager([new Deflate()])),
    null
);
$tokenDecrypter = new TokenDecrypter($JWELoader);

$authorizationService = new AuthorizationService(
    new TokenSetFactory(),
    $tokenSetVerifier,
    $responseTokenVerifier,
    $tokenDecrypter,
    $httpClient
);

客户端注册


use TMV\OpenIdClient\Service\RegistrationService;

$registration = new RegistrationService();

// registration
$metadata = $registration->register(
    $issuer,
    [
        'client_name' => 'My client name',
        'redirect_uris' => ['https://my-rp.com/callback'],
    ],
    'my-initial-token'
);

// read
$metadata = $registration->read($metadata['registration_client_uri'], $metadata['registration_access_token']);

// update
$metadata = $registration->update(
    $metadata['registration_client_uri'],
    $metadata['registration_access_token'],
    array_merge($metadata, [
        // new metadata
    ])
);

// delete
$registration->delete($metadata['registration_client_uri'], $metadata['registration_access_token']);

令牌自检

use TMV\OpenIdClient\Service\IntrospectionService;

$service = new IntrospectionService();

$params = $service->introspect($client, $token);

令牌撤回

use TMV\OpenIdClient\Service\RevocationService;

$service = new RevocationService();

$params = $service->revoke($client, $token);

请求对象

您可以使用 TMV\OpenIdClient\RequestObject\RequestObjectFactory 类创建一个授权请求的请求对象。

这将根据您的客户端元数据创建一个签名(可选加密)的 JWT 令牌。

use TMV\OpenIdClient\RequestObject\RequestObjectFactory;
use Jose\Component\Core\AlgorithmManager;

$algorithmManager = new AlgorithmManager([/* your algorithms */]);

$factory = new RequestObjectFactory($algorithmManager);
$requestObject = $factory->create($client, [/* custom params to include in the JWT*/]);

然后您可以使用它来创建 AuthRequest。

use TMV\OpenIdClient\Authorization\AuthRequest;

$authRequest = AuthRequest::fromParams([
    'client_id' => $client->getMetadata()->getClientId(),
    'redirect_uri' => $client->getMetadata()->getRedirectUris()[0],
    'request' => $requestObject,
]);

聚合和分布式声明

该库可以处理聚合和分布式声明。

use TMV\OpenIdClient\Claims\AggregateParser;
use TMV\OpenIdClient\Claims\DistributedParser;

$aggregatedParser = new AggregateParser();

$claims = $aggregatedParser->unpack($client, $userinfo);

$distributedParser = new DistributedParser();
$claims = $distributedParser->fetch($client, $userinfo);

使用中间件

有一些中间件和处理程序可用。

SessionCookieMiddleware

此中间件应始终位于中间件链的顶部,以提供 statenonce 参数的 cookie 会话。

要使用它,您应安装 dflydev/fig-cookies 软件包。

$ composer require "dflydev/fig-cookies:^2.0"
use TMV\OpenIdClient\Middleware\SessionCookieMiddleware;

$middleware = new SessionCookieMiddleware();

中间件提供了一个具有 TMV\OpenIdClient\Session\AuthSessionInterface 状态实例的 TMV\OpenIdClient\Session\AuthSessionInterface 属性,用于持久化会话数据。

使用其他会话存储

如果您有其他会话存储,您可以处理它,并在 TMV\OpenIdClient\Session\AuthSessionInterface 属性中提供 TMV\OpenIdClient\Session\AuthSessionInterface 实例。

ClientProviderMiddleware

此中间件应始终位于中间件链的顶部,以向其他中间件提供客户端。

use TMV\OpenIdClient\Middleware\ClientProviderMiddleware;

$client = $container->get('openid.clients.default');
$middleware = new ClientProviderMiddleware($client);

AuthRequestProviderMiddleware

此中间件提供用于与 AuthRedirectHandler 一起使用的认证请求。

use TMV\OpenIdClient\Middleware\AuthRequestProviderMiddleware;
use TMV\OpenIdClient\Authorization\AuthRequest;

$authRequest = AuthRequest::fromParams([
    'scope' => 'openid',
    // other params...
]);
$middleware = new AuthRequestProviderMiddleware($authRequest);

AuthRedirectHandler

此处理程序将用户重定向到 OpenID 授权页面。

use TMV\OpenIdClient\Middleware\AuthRedirectHandler;
use TMV\OpenIdClient\Service\AuthorizationService;

/** @var AuthorizationService $authorizationService */
$authorizationService = $container->get(AuthorizationService::class);
$middleware = new AuthRedirectHandler($authorizationService);

CallbackMiddleware

此中间件将处理来自 OpenID 提供者的回调。

它将提供具有最终 TokenSet 对象的 TMV\OpenIdClient\Token\TokenSetInterface 属性。

use TMV\OpenIdClient\Middleware\CallbackMiddleware;
use TMV\OpenIdClient\Service\AuthorizationService;

/** @var AuthorizationService $authorizationService */
$authorizationService = $container->get(AuthorizationService::class);
$middleware = new CallbackMiddleware($authorizationService);

UserinfoMiddleware

此中间件将从 userinfo 端点获取用户数据,并将提供具有用户信息的 TMV\OpenIdClient\Middleware\UserInfoMiddleware 属性(作为数组)。

use TMV\OpenIdClient\Middleware\UserInfoMiddleware;
use TMV\OpenIdClient\Service\UserinfoService;

/** @var UserinfoService $userinfoService */
$userinfoService = $container->get(UserinfoService::class);
$middleware = new UserInfoMiddleware($userinfoService);