if (!$this->checkAuthentication()) {
throw new InvalidCredentialsException('Usuário inválido.');
}
if (!$this->checkAuthorization()) {
throw new UnauthorizedException('Você não possui permissão.');
}
return new MyResponse([]);
Fonte: dracony.org
Psr\Http\Message\ServerRequestInterface
Psr\Http\Message\ResponseInterface
Psr\Http\Message\MessageInterface
Psr\Http\Message\RequestInterface
Psr\Http\Message\StreamInterface
Psr\Http\Message\UriInterface
Psr\Http\Message\UploadedFileInterface
use Interop\Http\ServerMiddleware\MiddlewareInterface;
use Psr\Http\Message\ServerRequestInterface as Request;
use Interop\Http\ServerMiddleware\DelegateInterface as Delegate;
class MyMiddleware implements MiddlewareInterface {
public function process(Request $request, Delegate $delegate) {
// Processa a requisição e retorna a resposta
// Ou chama o próximo middleware capaz de responder
return $delegate->process($request);
}
}
Fonte: PHP League OAuth 2.0 Server
aud
sub
jti
iss
iat
nbf
exp
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIxMjM0NTYiLCJhdWQiOiJQSFAgQ29uZmVyZW5jZSAyMDE3Iiwic3ViIjoiRXhlbXBsbyBKV1QiLCJ1c2VyIjp7ImlkIjoxLCJuYW1lIjoidmNhbXBpdGVsbGkifSwic2NvcGVzIjpbInNwZWFrZXIiXX0.8OZ6wkqtqfG9YjI5OGNN4Isyr5kdeZzhYIqHCC9u4cA
{
"alg": "HS256",
"typ": "JWT"
}
{
"jti": "123456",
"aud": "PHP Conference 2017",
"sub": "Exemplo JWT",
"user": {
"id": 1,
"name": "vcampitelli"
},
"scopes": [
"speaker"
]
}
HMACSHA256(
base64Url(header) + "." +
base64Url(payload),
"kJf;N%Z$K1oQ>dPN|LB?Vno$"
)
composer create-project zendframework/zend-expressive-skeleton
composer require league/oauth2-server
ConfigProvider
ResourceServerMiddleware
TokenAction
AuthorizationServer
AccessTokenEntity
AccessTokenRepository
ClientEntity
ClientRepository
ScopeEntity
ScopeRepository
public function getRoutes() {
return [
[
'name' => 'oauth.token',
'path' => '/token',
'middleware' => TokenAction::class,
'allowed_methods' => ['POST']
]
];
}
public function getDependencies() {
return [
'factories' => [
TokenAction::class => TokenActionFactory::class,
ClientRepository::class => RepositoryFactory::class,
ScopeRepository::class => RepositoryFactory::class,
AccessTokenRepository::class => RepositoryFactory::class,
ResourceServerMiddleware::class => ResourceServerFactory::class,
AuthorizationServer::class => AuthorizationServerFactory::class
]
];
}
public function process(
ServerRequestInterface $request,
DelegateInterface $delegate
) {
$request = $this->resourceServer->validateAuthenticatedRequest($request);
$clientId = $request->getAttribute('oauth_client_id');
if ((empty($clientId)) || (!$this->isClientAuthorized($clientId, $request))) {
throw OAuthServerException::accessDenied('Unauthorized client');
}
return $delegate->process($request);
}
public function process(
ServerRequestInterface $request,
DelegateInterface $delegate
) {
return $this->authorizationServer->handleTokenRequest($request);
}
public function handleTokenRequest(ServerRequestInterface $request) {
try {
$response = new \Zend\Diactoros\Response\JsonResponse([]);
return $this->authorizationServer
->respondToAccessTokenRequest($request, $response);
} catch (\League\OAuth2\Server\Exception\OAuthServerException $e) {
return $e->generateHttpResponse($response);
}
}
public function __invoke(ContainerInterface $container) {
$config = $container->get('config')['oauth'];
$server = new \League\OAuth2\Server\AuthorizationServer(
$container->get(ClientRepository::class),
$container->get(AccessTokenRepository::class),
$container->get(ScopeRepository::class),
$config['private_key'],
$config['encryption_key']
);
$server->enableGrantType(
new \League\OAuth2\Server\Grant\ClientCredentialsGrant(),
new \DateInterval('PT1H') // 1 hora para expiração
);
return $server;
}
public function finalizeScopes(
array $scopes,
$grantType,
ClientEntityInterface $clientEntity,
$userIdentifier = null
) {
// Valida os scopes que o cliente está pedindo,
// adicionando novos e removendo os inválidos
return $scopes;
}
public function convertToJWT(\League\OAuth2\Server\CryptKey $key) {
return (new \Lcobucci\JWT\Builder())
->setAudience('PHP Conference 2017')
->setSubject('OAuth 2 com JWT')
->set('scopes', $this->getScopes())
->setIssuedAt(time())
->setExpiration($this->getExpiryDateTime())
->sign(
new \Lcobucci\JWT\Signer\Rsa\Sha256(),
(new \Lcobucci\JWT\Signer\Key())->getPrivateKey(
$key->getKeyPath(),
$key->getPassphrase()
)
)->getToken();
}
curl -X POST -d client_id=api -d client_secret=mysecret \
-d scope="user_list user_create" https://api.local/token
{
"token_type": "Bearer",
"expires_in": 3600,
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6IjA1ODI3NTJkOTNiMTI4ZTYifQ.eyJhdWQiOiIxIiwic3ViIjoiIiwianRpIjoiMDU4Mjc1MmQ5M2IxMjhlNiIsInNjb3BlcyI6W10sImlhdCI6MTUwNzQwNTI0NCwiZXhwIjoxNTA3NDA4ODQ0fQ.P7V0TBzBOiTXqUk48wMFMhEPYjvT3EXOMqztRHXGqAmZJm7Uhd7jRejwwE-YBPu4lOcRhDsxoYbM5b_VVc1BRgGf824WpWdW1Mg5FALHTlGJqLvVmHYbZqPahBNei4_BXJmtZ7e7Vp9IkjY3qTR4W9h4BjieI7P0TLTIS0S3Q1c"
}
curl -X GET \
-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6IjA1ODI3NTJkOTNiMTI4ZTYifQ.eyJhdWQiOiIxIiwic3ViIjoiIiwianRpIjoiMDU4Mjc1MmQ5M2IxMjhlNiIsInNjb3BlcyI6W10sImlhdCI6MTUwNzQwNTI0NCwiZXhwIjoxNTA3NDA4ODQ0fQ.P7V0TBzBOiTXqUk48wMFMhEPYjvT3EXOMqztRHXGqAmZJm7Uhd7jRejwwE-YBPu4lOcRhDsxoYbM5b_VVc1BRgGf824WpWdW1Mg5FALHTlGJqLvVmHYbZqPahBNei4_BXJmtZ7e7Vp9IkjY3qTR4W9h4BjieI7P0TLTIS0S3Q1c" \
https://api.local/users
{ ... }
Zend Expressive com OAuth 2 e JWT