Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

of

Asegurando APIs en Symfony con JWT Slide 1 Asegurando APIs en Symfony con JWT Slide 2 Asegurando APIs en Symfony con JWT Slide 3 Asegurando APIs en Symfony con JWT Slide 4 Asegurando APIs en Symfony con JWT Slide 5 Asegurando APIs en Symfony con JWT Slide 6 Asegurando APIs en Symfony con JWT Slide 7 Asegurando APIs en Symfony con JWT Slide 8 Asegurando APIs en Symfony con JWT Slide 9 Asegurando APIs en Symfony con JWT Slide 10 Asegurando APIs en Symfony con JWT Slide 11 Asegurando APIs en Symfony con JWT Slide 12 Asegurando APIs en Symfony con JWT Slide 13 Asegurando APIs en Symfony con JWT Slide 14 Asegurando APIs en Symfony con JWT Slide 15 Asegurando APIs en Symfony con JWT Slide 16 Asegurando APIs en Symfony con JWT Slide 17 Asegurando APIs en Symfony con JWT Slide 18 Asegurando APIs en Symfony con JWT Slide 19 Asegurando APIs en Symfony con JWT Slide 20 Asegurando APIs en Symfony con JWT Slide 21 Asegurando APIs en Symfony con JWT Slide 22 Asegurando APIs en Symfony con JWT Slide 23 Asegurando APIs en Symfony con JWT Slide 24 Asegurando APIs en Symfony con JWT Slide 25 Asegurando APIs en Symfony con JWT Slide 26 Asegurando APIs en Symfony con JWT Slide 27 Asegurando APIs en Symfony con JWT Slide 28 Asegurando APIs en Symfony con JWT Slide 29 Asegurando APIs en Symfony con JWT Slide 30 Asegurando APIs en Symfony con JWT Slide 31 Asegurando APIs en Symfony con JWT Slide 32 Asegurando APIs en Symfony con JWT Slide 33 Asegurando APIs en Symfony con JWT Slide 34 Asegurando APIs en Symfony con JWT Slide 35 Asegurando APIs en Symfony con JWT Slide 36 Asegurando APIs en Symfony con JWT Slide 37 Asegurando APIs en Symfony con JWT Slide 38 Asegurando APIs en Symfony con JWT Slide 39 Asegurando APIs en Symfony con JWT Slide 40 Asegurando APIs en Symfony con JWT Slide 41 Asegurando APIs en Symfony con JWT Slide 42 Asegurando APIs en Symfony con JWT Slide 43 Asegurando APIs en Symfony con JWT Slide 44 Asegurando APIs en Symfony con JWT Slide 45 Asegurando APIs en Symfony con JWT Slide 46 Asegurando APIs en Symfony con JWT Slide 47 Asegurando APIs en Symfony con JWT Slide 48 Asegurando APIs en Symfony con JWT Slide 49 Asegurando APIs en Symfony con JWT Slide 50 Asegurando APIs en Symfony con JWT Slide 51 Asegurando APIs en Symfony con JWT Slide 52 Asegurando APIs en Symfony con JWT Slide 53 Asegurando APIs en Symfony con JWT Slide 54 Asegurando APIs en Symfony con JWT Slide 55 Asegurando APIs en Symfony con JWT Slide 56 Asegurando APIs en Symfony con JWT Slide 57 Asegurando APIs en Symfony con JWT Slide 58 Asegurando APIs en Symfony con JWT Slide 59 Asegurando APIs en Symfony con JWT Slide 60 Asegurando APIs en Symfony con JWT Slide 61 Asegurando APIs en Symfony con JWT Slide 62 Asegurando APIs en Symfony con JWT Slide 63 Asegurando APIs en Symfony con JWT Slide 64 Asegurando APIs en Symfony con JWT Slide 65 Asegurando APIs en Symfony con JWT Slide 66 Asegurando APIs en Symfony con JWT Slide 67 Asegurando APIs en Symfony con JWT Slide 68 Asegurando APIs en Symfony con JWT Slide 69 Asegurando APIs en Symfony con JWT Slide 70 Asegurando APIs en Symfony con JWT Slide 71 Asegurando APIs en Symfony con JWT Slide 72 Asegurando APIs en Symfony con JWT Slide 73 Asegurando APIs en Symfony con JWT Slide 74 Asegurando APIs en Symfony con JWT Slide 75 Asegurando APIs en Symfony con JWT Slide 76 Asegurando APIs en Symfony con JWT Slide 77 Asegurando APIs en Symfony con JWT Slide 78 Asegurando APIs en Symfony con JWT Slide 79 Asegurando APIs en Symfony con JWT Slide 80 Asegurando APIs en Symfony con JWT Slide 81 Asegurando APIs en Symfony con JWT Slide 82 Asegurando APIs en Symfony con JWT Slide 83 Asegurando APIs en Symfony con JWT Slide 84 Asegurando APIs en Symfony con JWT Slide 85 Asegurando APIs en Symfony con JWT Slide 86 Asegurando APIs en Symfony con JWT Slide 87 Asegurando APIs en Symfony con JWT Slide 88 Asegurando APIs en Symfony con JWT Slide 89 Asegurando APIs en Symfony con JWT Slide 90 Asegurando APIs en Symfony con JWT Slide 91 Asegurando APIs en Symfony con JWT Slide 92 Asegurando APIs en Symfony con JWT Slide 93 Asegurando APIs en Symfony con JWT Slide 94 Asegurando APIs en Symfony con JWT Slide 95 Asegurando APIs en Symfony con JWT Slide 96 Asegurando APIs en Symfony con JWT Slide 97 Asegurando APIs en Symfony con JWT Slide 98 Asegurando APIs en Symfony con JWT Slide 99 Asegurando APIs en Symfony con JWT Slide 100 Asegurando APIs en Symfony con JWT Slide 101 Asegurando APIs en Symfony con JWT Slide 102 Asegurando APIs en Symfony con JWT Slide 103 Asegurando APIs en Symfony con JWT Slide 104 Asegurando APIs en Symfony con JWT Slide 105 Asegurando APIs en Symfony con JWT Slide 106 Asegurando APIs en Symfony con JWT Slide 107 Asegurando APIs en Symfony con JWT Slide 108 Asegurando APIs en Symfony con JWT Slide 109 Asegurando APIs en Symfony con JWT Slide 110 Asegurando APIs en Symfony con JWT Slide 111 Asegurando APIs en Symfony con JWT Slide 112 Asegurando APIs en Symfony con JWT Slide 113 Asegurando APIs en Symfony con JWT Slide 114 Asegurando APIs en Symfony con JWT Slide 115 Asegurando APIs en Symfony con JWT Slide 116 Asegurando APIs en Symfony con JWT Slide 117 Asegurando APIs en Symfony con JWT Slide 118 Asegurando APIs en Symfony con JWT Slide 119 Asegurando APIs en Symfony con JWT Slide 120 Asegurando APIs en Symfony con JWT Slide 121 Asegurando APIs en Symfony con JWT Slide 122 Asegurando APIs en Symfony con JWT Slide 123 Asegurando APIs en Symfony con JWT Slide 124 Asegurando APIs en Symfony con JWT Slide 125 Asegurando APIs en Symfony con JWT Slide 126 Asegurando APIs en Symfony con JWT Slide 127 Asegurando APIs en Symfony con JWT Slide 128 Asegurando APIs en Symfony con JWT Slide 129 Asegurando APIs en Symfony con JWT Slide 130 Asegurando APIs en Symfony con JWT Slide 131 Asegurando APIs en Symfony con JWT Slide 132 Asegurando APIs en Symfony con JWT Slide 133 Asegurando APIs en Symfony con JWT Slide 134 Asegurando APIs en Symfony con JWT Slide 135 Asegurando APIs en Symfony con JWT Slide 136 Asegurando APIs en Symfony con JWT Slide 137 Asegurando APIs en Symfony con JWT Slide 138
Upcoming SlideShare
What to Upload to SlideShare
Next
Download to read offline and view in fullscreen.

7 Likes

Share

Download to read offline

Asegurando APIs en Symfony con JWT

Download to read offline

Los JSON Web Tokens son una forma muy práctica de asegurar nuestras APIs.

En esta charla veremos cuáles son sus propiedades fundamentales, cómo trabajar con ellos y qué opciones tenemos en Symfony, tanto con librerías, como con LexikJWTAuthenticationBundle y su uso del componente Guard.

Related Books

Free with a 30 day trial from Scribd

See all

Related Audiobooks

Free with a 30 day trial from Scribd

See all

Asegurando APIs en Symfony con JWT

  1. 1. deSymfony 30 junio - 1 julio 2017 Castellón ASEGURANDO APIS EN SYMFONY CON JWT Nacho Martín
  2. 2. deSymfony ¡Muchas gracias a nuestros patrocinadores!
  3. 3. Programo en Limenius Casi todos los proyectos necesitan una API Hacemos aplicaciones a medida con Symfony y React JWT es una buena herramienta para asegurarlas
  4. 4. Por qué es esto necesario
  5. 5. Por qué es esto necesario ¿Por qué no está todo inventado?
  6. 6. Esta charla va de alivios
  7. 7. Esta charla va de alivios
  8. 8. Autenticación con Cookies Cliente (navegador) Servidor BD POST /login_check username: "nacho", password: "patata"
  9. 9. Autenticación con Cookies Cliente (navegador) Servidor BD Obtiene usuario Verifica credenciales Guarda sesión
  10. 10. Autenticación con Cookies Cliente (navegador) Servidor BD Envía cookie al cliente Set-Cookie: PHPSESSIONID=HOLA…
  11. 11. Autenticación con Cookies Cliente (navegador) Servidor BD Usa cookie para identificarse Cookie: PHPSESSIONID=HOLA
  12. 12. Problemas con Cookies Problemas con CORS Implementación no natural en algunos clientes Hay que protegerse contra CSRF Requiere una gestión de sesión y pensar en cómo escalar Mantienen un estado (sesión)
  13. 13. Estado en REST […] communication must be stateless in nature, […], such that each request from client to server must contain all of the information necessary to understand the request, and cannot take advantage of any stored context on the server. Session state is therefore kept entirely on the client.
  14. 14. Cómo siempre, hay razones Requiere una gestión de sesión, y pensar en cómo escalar ¿Qué hacer con un balanceador de carga? ¿Dónde guardar las sesiones?
  15. 15. Alternativas para APIs
  16. 16. Junio 2012
  17. 17. JSON Web Tokens (JWT)
  18. 18. JOSE JSON Object Signing and Encryption { JWT JWA JWS JWE JWK
  19. 19. JOSE JSON Object Signing and Encryption { JWT JWA JWS JWE JWK
  20. 20. JWT solo es un formato de tokens Pero muchas veces decimos “usar JWT” Para referirnos a una forma de trabajar con ellos https://www.flickr.com/photos/tokencompany/8073379662
  21. 21. Autenticación con JWT Cliente (navegador) Servidor BD POST /login_check username: "nacho", password: "patata"
  22. 22. Autenticación con JWT Cliente (navegador) Servidor BD Obtiene usuario Verifica credenciales Guarda sesión?
  23. 23. Autenticación con JWT Cliente (navegador) Servidor BD Envía token al cliente {“token”:"tomaUnToken"}
  24. 24. Autenticación con JWT Cliente (navegador) Servidor BD Usa token para identificarse Authorization: Bearer tomaUnToken
  25. 25. Uso en JavaScript fetch(baseUrl + '/admin/api/recipes', { method: 'POST', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', 'Authorization': 'Bearer '+token, }, body: JSON.stringify( data ) })
  26. 26. Almacenamiento en JavaScript window.localStorage.setItem('access_token', token) window.localStorage.getItem('access_token')
  27. 27. Almacenamiento en JavaScript window.localStorage.setItem('access_token', token) window.localStorage.getItem('access_token') Ya no tenemos CSRF, ahora ojo con ataques XSS
  28. 28. El famoso token eyJhbGciOiJSUzI1NiJ9.eyJyb2xlcyI6WyJST0xFX1VTRVIiXSwid XNlcm5hbWUiOiJuYWNobyIsImlhdCI6MTQ5ODE0MjA3Niw iZXhwIjoxNDk4MTQ1Njc2fQ
  29. 29. eyJhbGciOiJSUzI1NiJ9.eyJyb2xlcyI6WyJST0xFX1VTRVIiXSwid XNlcm5hbWUiOiJuYWNobyIsImlhdCI6MTQ5ODE0MjA3Niw iZXhwIjoxNDk4MTQ1Njc2fQ El famoso token
  30. 30. eyJhbGciOiJSUzI1NiJ9.eyJyb2xlcyI6WyJST0xFX1VTRVIiXSwid XNlcm5hbWUiOiJuYWNobyIsImlhdCI6MTQ5ODE0MjA3Niw iZXhwIjoxNDk4MTQ1Njc2fQ Hay un punto El famoso token
  31. 31. El famoso token eyJhbGciOiJSUzI1NiJ9.eyJyb2xlcyI6WyJST0xFX1VTRVIiXSwid XNlcm5hbWUiOiJuYWNobyIsImlhdCI6MTQ5ODE0MjA3Niw iZXhwIjoxNDk4MTQ1Njc2fQ
  32. 32. El famoso token eyJhbGciOiJSUzI1NiJ9.eyJyb2xlcyI6WyJST0xFX1VTRVIiXSwid XNlcm5hbWUiOiJuYWNobyIsImlhdCI6MTQ5ODE0MjA3Niw iZXhwIjoxNDk4MTQ1Njc2fQ {“alg":"none"} { “username":"nacho", “iat":1498142076, “exp”:1498145676 }
  33. 33. Base64Url eyJhbGciOiJSUzI1NiJ9{“alg":"none"} No está cifrado (todos lo pueden leer) Solo está codificado Esto solo sirve para que pueda viajar en URLs Y en cualquier sitio donde puedan viajar strings
  34. 34. Base64Url { “username":"nacho", “iat":1498142076, “exp”:1498145676 } ¿Me puedo fiar de esto?
  35. 35. Base64Url { “username":"nacho", “iat":1498142076, “exp”:1498145676 } ¿Me puedo fiar de esto?
  36. 36. El token completo eyJhbGciOiJSUzI1NiJ9.eyJyb2xlcyI6WyJST0xFX1VTRVIiXSwidXNlcm5hbWUiOiJuYWNobyIsImlhdCI6MTQ5ODE0MjA3NiwiZXh wIjoxNDk4MTQ1Njc2fQ.jomtnO16Tik6jxU_0HmsXFxbUSyBoNTu8RVSbQ9jEKUfYEFTG8QZrsSpNl5uzlXf- hP2zx1YmPTow1jXGyoFjV6Nk1e7pFlw2s8fSrIZpT2ZFBuVPefKhSWXYoSUHGZWtMFMU- yghnWA6tlFD5UcJiDQ3ZlUCbLxOlDdygUoC841aR9R87otefdQUEKY_faGq1Tl- KxJfjndG4HENgC7M52JaX5xFKmOlI1mKXqDvVOrCTil3yOcqxQv94SZjqhG5V7NLaaslMDXVl4fzJC- WWE_Eo0xzfOSxMAZ7NBEvha207pjl8FAszQDZ0uuqxfPLqb4QnpALnFAGip4hlu28wRccAsWJQ6uSYtClrE9Kwt7Vlo4PrPX3zqMb _YaRI1QUco6qjj2AsCf18-0f5XvgqrwSoU_73w4pgsj7rUyft9mwe3tiUYCoUP_dKFJfcz_ofHScpsWfFJ4lD4TIzpKf1LfLFwRUcpQuJdR K8-1C_x5dJILrO2fSKZbxFCq_- zB2UHmbH8eFQQYxIpS4eDjFDZTeFLOzruapM10taDQ8buGOyVUx9vwTJoWq9dFuqVAdhFc9h6iXNy0QzI46uvN- en1n6KVsKTfaLecvCYhIIt32Z5mYD3YgDEeRnLZ5TIgykiVNL9SZCGphzv6h5MEs_xQyDo6XOsu92tPtbqyvI4
  37. 37. El token completo eyJhbGciOiJSUzI1NiJ9.eyJyb2xlcyI6WyJST0xFX1VTRVIiXSwidXNlcm5hbWUiOiJuYWNobyIsImlhdCI6MTQ5ODE0MjA3NiwiZXh wIjoxNDk4MTQ1Njc2fQ.jomtnO16Tik6jxU_0HmsXFxbUSyBoNTu8RVSbQ9jEKUfYEFTG8QZrsSpNl5uzlXf- hP2zx1YmPTow1jXGyoFjV6Nk1e7pFlw2s8fSrIZpT2ZFBuVPefKhSWXYoSUHGZWtMFMU- yghnWA6tlFD5UcJiDQ3ZlUCbLxOlDdygUoC841aR9R87otefdQUEKY_faGq1Tl- KxJfjndG4HENgC7M52JaX5xFKmOlI1mKXqDvVOrCTil3yOcqxQv94SZjqhG5V7NLaaslMDXVl4fzJC- WWE_Eo0xzfOSxMAZ7NBEvha207pjl8FAszQDZ0uuqxfPLqb4QnpALnFAGip4hlu28wRccAsWJQ6uSYtClrE9Kwt7Vlo4PrPX3zqMb _YaRI1QUco6qjj2AsCf18-0f5XvgqrwSoU_73w4pgsj7rUyft9mwe3tiUYCoUP_dKFJfcz_ofHScpsWfFJ4lD4TIzpKf1LfLFwRUcpQuJdR K8-1C_x5dJILrO2fSKZbxFCq_- zB2UHmbH8eFQQYxIpS4eDjFDZTeFLOzruapM10taDQ8buGOyVUx9vwTJoWq9dFuqVAdhFc9h6iXNy0QzI46uvN- en1n6KVsKTfaLecvCYhIIt32Z5mYD3YgDEeRnLZ5TIgykiVNL9SZCGphzv6h5MEs_xQyDo6XOsu92tPtbqyvI4 header.claims.signature
  38. 38. Pero sí está firmado (los intermediarios no lo pueden modificar sin que nos enteremos) No está cifrado
  39. 39. Header { “typ”:”JWT”, “alg”:”RS256” }
  40. 40. Header { “typ”:”JWT”, “alg”:”RS256” } Tipo de token
  41. 41. Header { “typ”:”JWT”, “alg”:”RS256” } Tipo de token Algoritmo de hashing
  42. 42. ¿Qué algoritmo usar? JWA (rfc7518)
  43. 43. Diferencia simétrico/asimétrico Simétrico: usamos la misma clave para firmar y validar. Asimétrico: usamos distintas claves para firmar y validar.
  44. 44. RS256 RS384 RS512 Algoritmos HS256 HS384 HS512 ES256 ES384 ES512 HMAC ECDSA RSA PS256 PS384 PS348 RSASSA-PSS none
  45. 45. RS256 RS384 RS512 Algoritmos HS256 HS384 HS512 ES256 ES384 ES512 HMAC ECDSA RSA PS256 PS384 PS348 RSASSA-PSS none Simétrico
  46. 46. RS256 RS384 RS512 Algoritmos HS256 HS384 HS512 ES256 ES384 ES512 HMAC ECDSA RSA PS256 PS384 PS348 RSASSA-PSS none Simétrico Asimétricos
  47. 47. RS256 RS384 RS512 Algoritmos HS256 HS384 HS512 ES256 ES384 ES512 HMAC ECDSA RS256 RS384 RS512 RSA PS256 PS384 PS348 RSASSA-PSS none Simétrico Asimétricos
  48. 48. Claims { “username":"nacho", “iat":1498142076, “exp”:1498145676 }
  49. 49. Registered claims jti iss aud sub iat exp nbf Id del token: String Issuer (emisor): StringOrUri Audiencia: StringOrUri Subject (tema): StringOrUri Cuándo se creó: NumericDate Cuándo expira: NumericDate Tiempo hasta válidez: NumericDate
  50. 50. Custom claims { “username":"nacho", “iat":1498142076, “exp”:1498145676 } Podemos añadir lo que queramos. Solo hay que tener en cuenta: Ser conciso. Los datos no van cifrados (el cliente los ve).
  51. 51. Firma Signature = algoritmo(payload, key) Payload = Base64URL(headers) + ”.” + Base64URL(claims) JWS (rfc7515)
  52. 52. JWT.IO
  53. 53. Importante: Usar TLS (“SSL”)
  54. 54. Ventajas de JWT
  55. 55. Caso: Mi app en JavaScript se ve distinta dependiendo del rol del usuario
  56. 56. Con Cookies Cliente Servidor BD Cookie: PHPSESSIONID=HOLA
  57. 57. Con Cookies Cliente Servidor BD Cookie: PHPSESSIONID=HOLA Tengo una cookie pero no sé qué usuario soy ni qué permisos tengo
  58. 58. Con Cookies Cliente Servidor BD Cookie: PHPSESSIONID=HOLA
  59. 59. Con Cookies Cliente Servidor BD Cookie: PHPSESSIONID=HOLA Obtener usuario
  60. 60. Con Cookies Cliente Servidor BD Cookie: PHPSESSIONID=HOLA Obtener usuario
  61. 61. Con Cookies Cliente Servidor BD Cookie: PHPSESSIONID=HOLA Obtener usuario
  62. 62. Con Cookies Cliente Servidor BD Cookie: PHPSESSIONID=HOLA Obtener usuario
  63. 63. Con Cookies Cliente Servidor BD Cookie: PHPSESSIONID=HOLA Obtener usuario Y ahora mostramos
  64. 64. Con JWT Cliente Servidor BD Token: ejh9…
  65. 65. Con JWT Cliente Servidor BD Token: ejh9… { “username":"nacho", “iat":1498142076, “exp”:1498145676 }
  66. 66. Con JWT Cliente Servidor BD Token: ejh9… { “username":"nacho", “iat":1498142076, “exp”:1498145676 } Tenemos todos los datos
  67. 67. Con JWT Cliente Token: ejh9… { “username":"nacho", “iat":1498142076, “exp”:1498145676 } Tenemos todos los datos
  68. 68. Microservicios Auth Clave privada y pública Consulta Clave pública Cliente Clave pública Pedidos Clave pública
  69. 69. Microservicios Auth Clave privada y pública Consulta Clave pública Cliente Clave pública Pedidos Clave pública { “aud”:”consulta", }
  70. 70. Microservicios Auth Clave privada y pública Consulta Clave pública Cliente Clave pública Pedidos Clave pública { “aud”:”consulta", } ✘
  71. 71. Microservicios Auth Clave privada Consulta Cliente Clave pública Clave pública Pedidos Gateway
  72. 72. Soporte en PHP
  73. 73. lcobucci/jwt
  74. 74. Crear tokens use LcobucciJWTBuilder; use LcobucciJWTSignerKeychain; use LcobucciJWTSignerRsaSha256; $signer = new Sha256(); $keychain = new Keychain(); $privateKey = $keychain->getPrivateKey('file://path'); $token = (new Builder())->setIssuer('http://example.com') ->setAudience('http://example.org') ->setId('4f1g23a12aa', true) ->setIssuedAt(time()) ->setNotBefore(time() + 60) ->setExpiration(time() + 3600) ->set('uid', 1) ->sign($signer, $privateKey) ->getToken();
  75. 75. Validar tokens use LcobucciJWTSignerKeychain; use LcobucciJWTSignerRsaSha256; use LcobucciJWTValidationData; $signer = new Sha256(); $keychain = new Keychain(); $publicKey = $keychain->getPublicKey('file://path'); $data = newValidationData(); $data->setIssuer('http://example.com'); $data->setAudience('http://example.org'); $data->setId('4f1g23a12aa'); $token->validate($data); $token->verify($signer, $publicKey);
  76. 76. LexikJWTAuthenticationBundle
  77. 77. Instalación composer require lexik/jwt-authentication-bundle $bundles = array( // ... new LexikBundleJWTAuthenticationBundleLexikJWTAuthenticationBundle(), // ... ); app/config/AppKernel.php
  78. 78. Crear claves $ openssl genrsa -out var/jwt/private.pem -aes256 4096 $ openssl rsa -pubout -in app/jwt/private.pem -out var/jwt/public.pem
  79. 79. Crear claves $ openssl genrsa -out var/jwt/private.pem -aes256 4096 $ openssl rsa -pubout -in app/jwt/private.pem -out var/jwt/public.pem Clave privada
  80. 80. Crear claves $ openssl genrsa -out var/jwt/private.pem -aes256 4096 $ openssl rsa -pubout -in app/jwt/private.pem -out var/jwt/public.pem Clave privada Clave pública
  81. 81. Configuración app/config/parameters.yml app/config/config.yml lexik_jwt_authentication: private_key_path: %jwt_private_key_path% public_key_path: %jwt_public_key_path% pass_phrase: %jwt_key_pass_phrase% token_ttl: %jwt_token_ttl% parameters: jwt_private_key_path: '%kernel.root_dir%/../var/jwt/private.pem' jwt_public_key_path: '%kernel.root_dir%/../var/jwt/public.pem' jwt_key_pass_phrase: patata jwt_token_ttl: 3600
  82. 82. Configuración app/config/parameters.yml app/config/config.yml lexik_jwt_authentication: private_key_path: %jwt_private_key_path% public_key_path: %jwt_public_key_path% pass_phrase: %jwt_key_pass_phrase% token_ttl: %jwt_token_ttl% encoder: service: lexik_jwt_authentication.encoder.lcobucci parameters: jwt_private_key_path: '%kernel.root_dir%/../var/jwt/private.pem' jwt_public_key_path: '%kernel.root_dir%/../var/jwt/public.pem' jwt_key_pass_phrase: patata jwt_token_ttl: 3600
  83. 83. Configuración app/config/parameters.yml app/config/config.yml lexik_jwt_authentication: private_key_path: %jwt_private_key_path% public_key_path: %jwt_public_key_path% pass_phrase: %jwt_key_pass_phrase% token_ttl: %jwt_token_ttl% encoder: service: lexik_jwt_authentication.encoder.lcobucci parameters: jwt_private_key_path: '%kernel.root_dir%/../var/jwt/private.pem' jwt_public_key_path: '%kernel.root_dir%/../var/jwt/public.pem' jwt_key_pass_phrase: patata jwt_token_ttl: 3600 Probablemente será default en algún punto
  84. 84. firewalls: login: pattern: ^/api/login stateless: true anonymous: true form_login: check_path: /api/login_check success_handler: lexik_jwt_authentication.handler.authentication_success failure_handler: lexik_jwt_authentication.handler.authentication_failure require_previous_session: false api: pattern: ^/api stateless: true guard: authenticators: - lexik_jwt_authentication.jwt_token_authenticator Security config app/config/security.yml
  85. 85. firewalls: login: pattern: ^/api/login stateless: true anonymous: true form_login: check_path: /api/login_check success_handler: lexik_jwt_authentication.handler.authentication_success failure_handler: lexik_jwt_authentication.handler.authentication_failure require_previous_session: false api: pattern: ^/api stateless: true guard: authenticators: - lexik_jwt_authentication.jwt_token_authenticator Security config app/config/security.yml No asigna cookies
  86. 86. Routing config app/config/routing.yml api_login_check: path: /api/login_check
  87. 87. Extender el bundle
  88. 88. Eventos JWT_CREATED: Añadir/quitar datos a claims. JWT_DECODED: Validaciones extra. JWT_AUTHENTICATED: Añadir datos al token de Symfony. AUTHENTICATION_FAILURE JWT_INVALID JWT_NOT_FOUND JWT_EXPIRED }Cambiar respuestas. AUTHENTICATION_SUCCESS
  89. 89. Añadir/quitar datos a payload class JWTCreatedListener { public function onJWTCreated(JWTCreatedEvent $event) { $payload = $event->getData(); $user = $event->getUser(); if ($user->canOrder()) { $payload['aud'] = ‘pedidos'; } $event->setData($payload); } }
  90. 90. Comprobaciones extra class JWTDecodedListener { public function onJWTDecoded(JWTDecodedEvent $event) { $payload = $event->getPayload(); if (!isset($payload['aud']) || $payload['aud'] !== 'pedidos') { $event->markAsInvalid(); } } }
  91. 91. Añadir atributo API a Token Sf class JWTAuthenticatedListener { public function onJWTAuthenticated(JWTAuthenticatedEvent $event) { $token = $event->getToken(); $token->setAttribute('api', true); } } public function pagesAction(Request $request) { if ($this->get(‘security.token_storage') ->getToken() ->getAttribute(‘api')) { return new JsonResponse('hola usuario de api'); } }
  92. 92. ¿Qué pasa si quiero…? Tener diferentes estrategias en distintos firewalls Hacer algo muy particular
  93. 93. Security
  94. 94. AuthenticationProviderInterface Security
  95. 95. AuthenticationProviderInterface UserProvider Security
  96. 96. AuthenticationEntryPointInterface AuthenticationProviderInterface UserProvider Security
  97. 97. AuthenticationListener AuthenticationEntryPointInterface AuthenticationProviderInterface UserProvider Security
  98. 98. AuthenticationListener AuthenticationEntryPointInterface AuthenticationProviderInterface UserProvider Security Events
  99. 99. AuthenticationListener AuthenticationEntryPointInterface AuthenticationProviderInterface UserProvider Security Events UserInterface
  100. 100. AuthenticationListener AuthenticationEntryPointInterface AuthenticationProviderInterface AbstractToken UserProvider Security Events UserInterface
  101. 101. AuthenticationListener AuthenticationEntryPointInterface AuthenticationProviderInterface AbstractToken UserProvider Security Voters Events UserInterface
  102. 102. UserProvider
  103. 103. UserProvider
  104. 104. 👌
  105. 105. AuthenticationListener AuthenticationEntryPointInterface AuthenticationProviderInterface AbstractToken UserProvider Security Voters Events UserInterface
  106. 106. Guard 💂
  107. 107. 👌
  108. 108. La interfaz GuardAuthenticator interface GuardAuthenticatorInterface { public function getCredentials(Request $request); public function getUser($credentials, UserProviderInterface $userProvider); public function checkCredentials($credentials, UserInterface $user); public function createAuthenticatedToken(UserInterface $user, $providerKey); public function onAuthenticationFailure(Request $request,AuthenticationException $exception); public function onAuthenticationSuccess(Request $request,TokenInterface $token, $providerKey); public function supportsRememberMe(); }
  109. 109. La interfaz GuardAuthenticator getCredentials getUser checkCredentials createAuthenticatedToken onAuthenticationFailure onAuthenticationSuccess supportsRememberMe
  110. 110. La interfaz GuardAuthenticator getCredentials getUser checkCredentials createAuthenticatedToken onAuthenticationFailure onAuthenticationSuccess supportsRememberMe Validar token
  111. 111. La interfaz GuardAuthenticator getCredentials getUser checkCredentials createAuthenticatedToken onAuthenticationFailure onAuthenticationSuccess supportsRememberMe Validar token Obtener usuario a partir de JWT
  112. 112. La interfaz GuardAuthenticator getCredentials getUser checkCredentials createAuthenticatedToken onAuthenticationFailure onAuthenticationSuccess supportsRememberMe Validar token Obtener usuario a partir de JWT true
  113. 113. La interfaz GuardAuthenticator getCredentials getUser checkCredentials createAuthenticatedToken onAuthenticationFailure onAuthenticationSuccess supportsRememberMe Validar token Obtener usuario a partir de JWT true Crear token de Symfony (no JWT)
  114. 114. La interfaz GuardAuthenticator getCredentials getUser checkCredentials createAuthenticatedToken onAuthenticationFailure onAuthenticationSuccess supportsRememberMe Devolver respuesta adecuada Validar token Obtener usuario a partir de JWT true Crear token de Symfony (no JWT)
  115. 115. La interfaz GuardAuthenticator getCredentials getUser checkCredentials createAuthenticatedToken onAuthenticationFailure onAuthenticationSuccess supportsRememberMe No hacer nada Devolver respuesta adecuada Validar token Obtener usuario a partir de JWT true Crear token de Symfony (no JWT)
  116. 116. La interfaz GuardAuthenticator getCredentials getUser checkCredentials createAuthenticatedToken onAuthenticationFailure onAuthenticationSuccess supportsRememberMe false No hacer nada Devolver respuesta adecuada Validar token Obtener usuario a partir de JWT true Crear token de Symfony (no JWT)
  117. 117. La interfaz GuardAuthenticator getCredentials getUser checkCredentials createAuthenticatedToken onAuthenticationFailure onAuthenticationSuccess supportsRememberMe false No hacer nada Devolver respuesta adecuada Validar token Obtener usuario a partir de JWT true Crear token de Symfony (no JWT)
  118. 118. JWTTokenAuthenticator use LexikBundleJWTAuthenticationBundleSecurityGuardJWTTokenAuthenticator as BaseAuthenticator; class MiTokenAuthenticator extends BaseAuthenticator { } security: # ... firewalls: # ... otra_api: pattern: ^/otraapi stateless: true guard: authenticators: - app.mi_token_authenticator
  119. 119. FAQ
  120. 120. Oauth vs JWT? Oauth + JWT?
  121. 121. Usos fuera de headers token_extractors: authorization_header: enabled: true prefix: Bearer name: Authorization cookie: enabled: false name: BEARER query_parameter: enabled: false name: bearer
  122. 122. Cuántos datos caben en un token? https://www.flickr.com/photos/highwaysagency/6008275527
  123. 123. Invalidar tokens
  124. 124. Enlaces con caducidad $user = $this->getUser(); $jwtManager = $this->get('lexik_jwt_authentication.jwt_manager'); $token2 = $jwtManager->create($user); <a href="{{ path('reset_password', {'bearer':authToken.credentials}) }}”> Reset password </a> Controlador Vista
  125. 125. Renovar tokens 👌
  126. 126. Impersonar usuarios en APIs 👌
  127. 127. Impersonar usuarios en APIs HEADER: X-Switch-User: johndoe
  128. 128. Requests a otros dominios 👌
  129. 129. Ejemplo de uso con React
  130. 130. ¡Gracias! @nacmartin nacho@limenius.com http://limenius.com Formación, consultoría y desarrollo de proyectos
  • JaviHernndezGil

    Oct. 4, 2018
  • ciclao22

    Jun. 4, 2018
  • nerdhacker

    Apr. 2, 2018
  • slaimer

    Sep. 14, 2017
  • FernandoCaveroMigule

    Aug. 8, 2017
  • domingo.gallardo

    Jul. 4, 2017
  • xfornesa

    Jul. 3, 2017

Los JSON Web Tokens son una forma muy práctica de asegurar nuestras APIs. En esta charla veremos cuáles son sus propiedades fundamentales, cómo trabajar con ellos y qué opciones tenemos en Symfony, tanto con librerías, como con LexikJWTAuthenticationBundle y su uso del componente Guard.

Views

Total views

4,010

On Slideshare

0

From embeds

0

Number of embeds

216

Actions

Downloads

41

Shares

0

Comments

0

Likes

7

×