Slide 1

Slide 1 text

Zend Expressive com OAuth 2 e JWT @vcampitelli Zend Expressive com OAuth 2 e JWT 1

Slide 2

Slide 2 text

Zend Expressive com OAuth 2 e JWT @vcampitelli Quem sou eu? Vinícius Campitelli • MT4 Tecnologia • @MediaPost • Curseduca @vcampitelli 2

Slide 3

Slide 3 text

Zend Expressive com OAuth 2 e JWT @vcampitelli Zend Expressive Middlewares PSR-7 PSR-15 3

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

Zend Expressive com OAuth 2 e JWT @vcampitelli Middlewares Fonte: dracony.org 5

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

Zend Expressive com OAuth 2 e JWT @vcampitelli Papéis Resource Owner: Usuário Client: Aplicação Authorization Server: API Resource Server: API * 9

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

Zend Expressive com OAuth 2 e JWT @vcampitelli Referências Site o cial https://jwt.io 11 . 3

Slide 16

Slide 16 text

Zend Expressive com OAuth 2 e JWT @vcampitelli Exemplo eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ 9.eyJqdGkiOiIxMjM0NTYiLCJhdWQiOiJQS FAgQ29uZmVyZW5jZSAyMDE3Iiwic3ViIjoi RXhlbXBsbyBKV1QiLCJ1c2VyIjp7ImlkIjo xLCJuYW1lIjoidmNhbXBpdGVsbGkifSwic2 NvcGVzIjpbInNwZWFrZXIiXX0.8OZ6wkqtq fG9YjI5OGNN4Isyr5kdeZzhYIqHCC9u4cA 12

Slide 17

Slide 17 text

Zend Expressive com OAuth 2 e JWT @vcampitelli Na Prática 13

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

Zend Expressive com OAuth 2 e JWT @vcampitelli 15

Slide 20

Slide 20 text

Zend Expressive com OAuth 2 e JWT @vcampitelli Classes ConfigProvider ResourceServerMiddleware TokenAction AuthorizationServer AccessTokenEntity AccessTokenRepository ClientEntity ClientRepository ScopeEntity ScopeRepository 16

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

Zend Expressive com OAuth 2 e JWT @vcampitelli Exemplo 25

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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