Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Zend Expressive com OAuth 2 e JWT

Zend Expressive com OAuth 2 e JWT

Palestra apresentada no PHPeste 2017 em Fortaleza e na PHP Conference 2017 em Osasco.

Link original da palestra: https://viniciuscampitelli.com/slides/expressive-oauth2-jwt/

* Zend Expressive 2
- Introdução e apresentação dos conceitos
- MIddlewares
- PSR-7
- PSR-15

* OAuth 2
- Introdução
- Papéis
- Access tokens, scopes e refresh tokens
- Grant types

* JWT (JSON Web Tokens)
- Introdução
- Geração de access tokens

Vinícius Campitelli

October 08, 2017
Tweet

More Decks by Vinícius Campitelli

Other Decks in Programming

Transcript

  1. Zend Expressive com OAuth 2 e JWT @vcampitelli Quem sou

    eu? Vinícius Campitelli • MT4 Tecnologia • @MediaPost • Curseduca @vcampitelli 2
  2. Zend Expressive com OAuth 2 e JWT @vcampitelli API 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([]); 4
  3. Zend Expressive com OAuth 2 e JWT @vcampitelli PSR-7 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 http://www.php- g.org/psr/psr-7/ 6
  4. Zend Expressive com OAuth 2 e JWT @vcampitelli PSR-15 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); } } 7
  5. Zend Expressive com OAuth 2 e JWT @vcampitelli OAuth 2

    Protocolo de autorização Para aplicações terceiras Para o próprio cliente 8
  6. Zend Expressive com OAuth 2 e JWT @vcampitelli Papéis Resource

    Owner: Usuário Client: Aplicação Authorization Server: API Resource Server: API * 9
  7. Zend Expressive com OAuth 2 e JWT @vcampitelli Tokens Access

    Token Refresh Token Grant Types Client credentials Authorization code Implicit Resource owner credentials 10 . 1
  8. Zend Expressive com OAuth 2 e JWT @vcampitelli Start Client

    Credentials Grant Authorization Code Grant Implicit Grant Password Grant Access token owner? Client type? First party or third party client? First party or third party client? Machine User User-agent-based app First party First party Third party Third party Web app Native app Fonte: PHP League OAuth 2.0 Server 10 . 2
  9. Zend Expressive com OAuth 2 e JWT @vcampitelli Referências Site

    o cial PHP League OAuth 2.0 Server Stormpath: What the Heck is OAuth? https://oauth.net/2 https://oauth2.thephpleague.com https://stormpath.com/blog/what-the-heck-is- oauth 10 . 3
  10. Zend Expressive com OAuth 2 e JWT @vcampitelli JWT JSON

    Web Tokens Padrão para representar claims Dividido em header, payload e signature Assinado com HMAC ou RSA 11 . 1
  11. Zend Expressive com OAuth 2 e JWT @vcampitelli Claims Audience:

    aud Subject: sub Identi er: jti Issuer: iss Issued At: iat Not Before: nbf Expiration: exp 11 . 2
  12. Zend Expressive com OAuth 2 e JWT @vcampitelli Exemplo eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ

    9.eyJqdGkiOiIxMjM0NTYiLCJhdWQiOiJQS FAgQ29uZmVyZW5jZSAyMDE3Iiwic3ViIjoi RXhlbXBsbyBKV1QiLCJ1c2VyIjp7ImlkIjo xLCJuYW1lIjoidmNhbXBpdGVsbGkifSwic2 NvcGVzIjpbInNwZWFrZXIiXX0.8OZ6wkqtq fG9YjI5OGNN4Isyr5kdeZzhYIqHCC9u4cA 12
  13. Zend Expressive com OAuth 2 e JWT @vcampitelli Instalação Fonte:

    composer create-project zendframework/zend-expressive-skeleton composer require league/oauth2-server github.com/zendframework/zend-expressive-skeleton 14
  14. Zend Expressive com OAuth 2 e JWT @vcampitelli Classes ConfigProvider

    ResourceServerMiddleware TokenAction AuthorizationServer AccessTokenEntity AccessTokenRepository ClientEntity ClientRepository ScopeEntity ScopeRepository 16
  15. Zend Expressive com OAuth 2 e JWT @vcampitelli Con gProvider

    public function getRoutes() { return [ [ 'name' => 'oauth.token', 'path' => '/token', 'middleware' => TokenAction::class, 'allowed_methods' => ['POST'] ] ]; } 17
  16. Zend Expressive com OAuth 2 e JWT @vcampitelli Con gProvider

    public function getDependencies() { return [ 'factories' => [ TokenAction::class => TokenActionFactory::clas ClientRepository::class => RepositoryFactory::class ScopeRepository::class => RepositoryFactory::class AccessTokenRepository::class => RepositoryFactory::class ResourceServerMiddleware::class => ResourceServerFactory::c AuthorizationServer::class => AuthorizationServerFacto ] ]; } 18
  17. Zend Expressive com OAuth 2 e JWT @vcampitelli ResourceServerMiddleware 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); } 19
  18. Zend Expressive com OAuth 2 e JWT @vcampitelli TokenAction public

    function process( ServerRequestInterface $request, DelegateInterface $delegate ) { return $this->authorizationServer->handleTokenRequest($request) } 20
  19. Zend Expressive com OAuth 2 e JWT @vcampitelli AuthorizationServer public

    function handleTokenRequest(ServerRequestInterface $reques try { $response = new \Zend\Diactoros\Response\JsonResponse([]); return $this->authorizationServer ->respondToAccessTokenRequest($request, $response); } catch (\League\OAuth2\Server\Exception\OAuthServerException $ return $e->generateHttpResponse($response); } } 21
  20. Zend Expressive com OAuth 2 e JWT @vcampitelli AuthorizationServerFactory 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; } 22
  21. Zend Expressive com OAuth 2 e JWT @vcampitelli ScopeRepository 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; } 23
  22. Zend Expressive com OAuth 2 e JWT @vcampitelli AccessTokenEntity 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() ) 24
  23. Zend Expressive com OAuth 2 e JWT @vcampitelli 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": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6I jA1ODI3NTJkOTNiMTI4ZTYifQ.eyJhdWQiOiIxIiwic3ViIjoiIiwianRpIjoiMD U4Mjc1MmQ5M2IxMjhlNiIsInNjb3BlcyI6W10sImlhdCI6MTUwNzQwNTI0NCwiZX hwIjoxNTA3NDA4ODQ0fQ.P7V0TBzBOiTXqUk48wMFMhEPYjvT3EXOMqztRHXGqAm ZJm7Uhd7jRejwwE-YBPu4lOcRhDsxoYbM5b_VVc1BRgGf824WpWdW1Mg5FALHTlG JqLvVmHYbZqPahBNei4_BXJmtZ7e7Vp9IkjY3qTR4W9h4BjieI7P0TLTIS0S3Q1 c" } 26
  24. Zend Expressive com OAuth 2 e JWT @vcampitelli curl -X

    GET \ -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsI mp0aSI6IjA1ODI3NTJkOTNiMTI4ZTYifQ.eyJhdWQiOiIxIiwic3ViIjoiIiwian RpIjoiMDU4Mjc1MmQ5M2IxMjhlNiIsInNjb3BlcyI6W10sImlhdCI6MTUwNzQwNT I0NCwiZXhwIjoxNTA3NDA4ODQ0fQ.P7V0TBzBOiTXqUk48wMFMhEPYjvT3EXOMqz tRHXGqAmZJm7Uhd7jRejwwE-YBPu4lOcRhDsxoYbM5b_VVc1BRgGf824WpWdW1Mg 5FALHTlGJqLvVmHYbZqPahBNei4_BXJmtZ7e7Vp9IkjY3qTR4W9h4BjieI7P0TLT IS0S3Q1c" \ https://api.local/users { ... } 27