EcuadorJUG2018
#RESTSecurity @CesarHgt @tomitribe
Deconstruyendo y
evolucionando la seguridad
en servicios REST
César Hernández
Tomitribe
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
César Hernández
• Senior Software Engineer at Tomitribe
• Java Champion
• Duke’s Choice Award 2016 y 2017
• Oracle Certified Professional
• +10 experience with Java EE
• Open Source advocate, teacher and
public speaker
Diapositivas
https://tribestream.io/ecuadorjug
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
“The nice thing about standards is
you have so many to choose from.”
- Andrew S. Tanenbaum
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
Áreas de Enfoque
• Más allá de Basic Auth
• Teoría de OAuth 2.0
• Introducción a JWT
• Google/Facebook style API security
• Arquitectura Stateless versus Stateful
• HTTP Signatures
• Amazon EC2 style API security
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018 Línea Base
1000 usuarios
x 3 TPS
4 saltos
3000 TPS
frontend
12000 TPS
backend
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
Basic Auth
(y sus problemas)
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
Mensaje en Basic Auth
POST /painter/color/object HTTP/1.1
Host: localhost:8443
Authorization: Basic c25vb3B5OnBhc3M=
User-Agent: curl/7.43.0
Accept: */*
Content-Type: application/json
Content-Length: 45
{"color":{"b":255,"g":0,"name":"blue","r":0}}
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018 Basic Auth
Password Sent
3000 TPS
(HTTP+SSL)
username+password
Base64 (no auth)
(LDAP)
12000 TPS
(HTTP)
3000 TPS
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018 Basic Auth
Password Sent
3000 TPS
(HTTP+SSL)
username+password
Base64
username+password
Base64
15000 TPS
(LDAP)
Password Sent
12000 TPS
(HTTP)
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018 Basic Auth
Password Sent
3000 TPS
(HTTP+SSL)
username+password
Base64
IP
whitelisting
3000 TPS
(LDAP)
12000 TPS
(HTTP)
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
“Dame toda la
información del
salario de José.”
“No se quien
eres,
…
pero por
supuesto!”
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
Ataque desde Latveria
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018 Ataque de fuerza bruta: Basic Auth
Password
válidos
3000 TPS
(HTTP+SSL) IP
whitelisting
9000 TPS
(LDAP)
12000 TPS
(HTTP)
Passwords
inválidos
6000 TPS
(HTTP+SSL)
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
OAuth 2.0
(y sus problemas)
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
OAuth 2 - Password Grant
(LDAP)
(Token Store)
POST /oauth2/token
Host: api.superbiz.io
User-Agent: curl/7.43.0
Accept: */*
Content-Type: application/x-www-form-urlencoded
Content-Length: 54
grant_type=password&username=snoopy&password=woodstock
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
"access_token":"2YotnFZFEjr1zCsicMWpAA",
"expires_in":3600,
"refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
}
Verificación de
Password
Generación de
Token
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
OAuth 2 - Password Grant
(LDAP)
(Token Store)
POST /oauth2/token
Host: api.superbiz.io
User-Agent: curl/7.43.0
Accept: */*
Content-Type: application/x-www-form-urlencoded
Content-Length: 54
grant_type=password&username=snoopy&password=woodstock
Verificación de
Password
Generación de
Token
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
"access_token":"2YotnFZFEjr1zCsicMWpAA",
"expires_in":3600,
"refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
}
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
OAuth 2.0 Message
POST /painter/color/object HTTP/1.1
Host: api.superbiz.io
Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA
User-Agent: curl/7.43.0
Accept: */*
Content-Type: application/json
Content-Length: 45
{"color":{"r":0,"g":0,"b":255,"name":"blue"}}
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
OAuth 2.0 Message
POST /painter/color/palette HTTP/1.1
Host: api.superbiz.io
Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA
User-Agent: curl/7.43.0
Accept: */*
Content-Type: application/json
Content-Length: 45
{"color":{"r":0,"g":255,"b":0,"name":"green"}}
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
OAuth 2.0 Message
POST /painter/color/select HTTP/1.1
Host: api.superbiz.io
Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA
User-Agent: curl/7.43.0
Accept: */*
Content-Type: application/json
Content-Length: 44
{"color":{"r":255,"g":0,"b":0,"name":"red"}}
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
OAuth 2.0 Message
POST /painter/color/fill HTTP/1.1
Host: api.superbiz.io
Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA
User-Agent: curl/7.43.0
Accept: */*
Content-Type: application/json
Content-Length: 49
{"color":{"r":0,"g":255,"b":255,"name":"yellow"}}
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
OAuth 2.0 Message
POST /painter/color/stroke HTTP/1.1
Host: api.superbiz.io
Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA
User-Agent: curl/7.43.0
Accept: */*
Content-Type: application/json
Content-Length: 49
{"color":{"r":255,"g":200,"b":255,"name":"orange"}}
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
401
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
OAuth 2 - Refresh Grant
(LDAP)
(Token Store)
Verify
Password
Generate
Token
POST /oauth2/token
Host: api.superbiz.io
User-Agent: curl/7.43.0
Accept: */*
Content-Type: application/x-www-form-urlencoded
Content-Length: 54
grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
"access_token":"6Fe4jd7TmdE5yW2q0y6W2w",
"expires_in":3600,
"refresh_token":"hyT5rw1QNh5Ttg2hdtR54e",
}
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
OAuth 2 - Refresh Grant
(LDAP)
(Token Store)
Verify
Password
Generate
Token
POST /oauth2/token
Host: api.superbiz.io
User-Agent: curl/7.43.0
Accept: */*
Content-Type: application/x-www-form-urlencoded
Content-Length: 54
grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
"access_token":"6Fe4jd7TmdE5yW2q0y6W2w",
"expires_in":3600,
"refresh_token":"hyT5rw1QNh5Ttg2hdtR54e",
}
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
Old pair
• Access Token 2YotnFZFEjr1zCsicMWpAA
• Refresh Token tGzv3JOkF0XG5Qx2TlKWIA
New pair
• Access Token 6Fe4jd7TmdE5yW2q0y6W2w
• Refresh Token hyT5rw1QNh5Ttg2hdtR54e
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
OAuth 2.0 Message
POST /painter/color/palette HTTP/1.1
Host: api.superbiz.io
Authorization: Bearer 6Fe4jd7TmdE5yW2q0y6W2w
User-Agent: curl/7.43.0
Accept: */*
Content-Type: application/json
Content-Length: 46
{"color":{"r":0,"g":255,"b":0,"name":"green"}}
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
OAuth 2.0 Message
POST /painter/color/select HTTP/1.1
Host: api.superbiz.io
Authorization: Bearer 6Fe4jd7TmdE5yW2q0y6W2w
User-Agent: curl/7.43.0
Accept: */*
Content-Type: application/json
Content-Length: 44
{"color":{"r":255,"g":0,"b":0,"name":"red"}}
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
OAuth 2.0 Message
POST /painter/color/fill HTTP/1.1
Host: api.superbiz.io
Authorization: Bearer 6Fe4jd7TmdE5yW2q0y6W2w
User-Agent: curl/7.43.0
Accept: */*
Content-Type: application/json
Content-Length: 49
{"color":{"r":0,"g":255,"b":255,"name":"yellow"}}
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
¿Qué hemos logrado?
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
Ahora tenemos más passwords
(al menos tus dispositivos los tienen)
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
Terminología de nuevo…
• Password Grant???
• Logging in
• Token?
• Un password ligeramente ofuscado
• Equivalente a un HTTP session ID mejorado levemente
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018 OAuth 2
Request enviados
(Authorization: Bearer …)
3000 TPS
(HTTP+SSL)
3000 TPS
(Verificaciones
de tokens)
Password enviados
(post oauth2/token …)
1000/daily
(HTTP+SSL)
OAuth 2
(LDAP)
4 saldos
12000 TPS
backend
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
“Quién es
6Fe4jd7TmdE5y
W2q0y6W2w
???????”
“No tengo idea.
Pregúntale al
servidor de
tokens.”
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018 OAuth 2
Tokens Sent
3000 TPS
(HTTP+SSL)
3000 TPS
(token checks)
Password Sent
1000/daily
(HTTP+SSL)
OAuth 2
(LDAP)
12000 TPS
(token checks)
8 hops
24000 TPS
backend
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018 OAuth 2
Tokens Sent
3000 TPS
(HTTP+SSL)
IP
whitelisting
3000 TPS
(token checks)
Password Sent
1000/daily
(HTTP+SSL)
OAuth 2
(LDAP)
12000 TPS
(token checks)
8 hops
24000 TPS
backend
55% of all traffic
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018 OAuth 2
Tokens Sent
3000 TPS
(HTTP+SSL)
IP
whitelisting
0 TPS
(token checks)
Password Sent
1000/daily
(HTTP+SSL)
OAuth 2
(LDAP)
0 TPS
(token checks)
0 hops
0 TPS
backend
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018 OAuth 2
Pointer Pointer
State
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
Access Token
Access Pointer?
Access Primary Key?
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
OAuth 2.0
High Frequency Password
Exchange Algorithm?
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
Hashing, Signing
Symmetric and Asymmetric
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018 Hashing Data
Tiene como entrada un conjunto de elementos, que suelen ser cadenas, y los
convierte en un rango de salida finito, normalmente cadenas de longitud fija.
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018 More Bits the Better
digests (hash values)
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
99 Bottles of Beer
mingus:~/bar 04:16:42
$ hashes all /tmp/party-time.txt
XxHash32 9237490d
XxHash64 81c4196cc7a01049
MD5 963462e4849e7c266df928b44b004190
SHA-1 b3be8c8879b31e7af4067f2769e4df37e6dd7690
SHA-256 0ef285da8792e1b78825f14ffc485a3843c66c4f481411978d0b4612be963383
SHA-512 376a589fd4b7f070119a8193e6d922df05d2f200c96927351bef66b688bffcca
3e990aa2f720494e95967bcbbfc804e86ec2eefea2f820e9a1aa2f3da5146fe7
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
99 Bottles of Water?
mingus:~/home 04:27:14
$ hashes all /tmp/party-time.txt #modified
XxHash32 2045608c
XxHash64 774507c9e384ea35
MD5 662028bba25e1e398ff8538cae9cd7c6
SHA-1 e11c127c072e09119fd7b3f35bc7ce1fd52b9b7a
SHA-256 671d8e4af11d7ee65c1d51ab29303a1afc7439402c2eb61505cfb5c698ff419c
SHA-512 fe0674683808e37bcad624d98426977c0936c15280922b2057efc33e4ca28127
8ea852d5450181fae726807e9c6e5e36a6823e7750948df89c6095ddbdaa4816
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018 Protegiendo el Hash
HMAC (Symmetric)
RSA (Asymmetric)
(public key)
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
Asymmetric key: https://youtu.be/E5FEqGYLL0o
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
OAuth 2.0
+
JSon Web Tokens (JWT)
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
JSon Web Token
• Pronunciado “YOT”
• JSON map con data de usuario
• Base64 URL Encoded
• Digitally Signed (RSA-SHA256, HMAC-SHA512, etc)
• Mecanismo de expiración
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
Previamente un Access Token
• 6Fe4jd7TmdE5yW2q0y6W2w
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
Access Token ahora (JWT)
• eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbi
10eXBlIjoiYWNjZXNzLXRva2VuIiwidXNlcm5hbWUiOiJzb
m9vcHkiLCJhbmltYWwiOiJiZWFnbGUiLCJpc3MiOiJodHRw
czovL2RlbW8uc3VwZXJiaXouY29tL29hdXRoMi90b2tlbiI
sInNjb3BlcyI6WyJ0d2l0dGVyIiwibWFucy1iZXN0LWZyaW
VuZCJdLCJleHAiOjE0NzQyODA5NjMsImlhdCI6MTQ3NDI3O
TE2MywianRpIjoiNjY4ODFiMDY4YjI0OWFkOSJ9.DTfSdMz
IIsC0j8z3icRdYO1GaMGl6j1I_2DBjiiHW9vmDz8OAw8Jh8
DpO32fv0vICc0hb4F0QCD3KQnv8GVM73kSYaOEUwlW0k1Ta
Elxc43_Ocxm1F5IUNZvzlLJ_ksFXGDL_cuadhVDaiqmhct0
98ocefuv08TdzRxqYoEqYNo
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
Access Token Now
• header (JSON > Base64 URL Encoded)
• Describe como la firma (signature) del token puede ser
verificada
• payload (JSON > Base64 URL Encoded)
• Json map de información que desees incluir
• Campo estándar como el de Expiración
• signature (Binary > Base64 URL Encoded)
• La firma digital
• Hecha exclusivamente por el endpoint: /oauth2/token
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018 • { "alg": “RS256", "typ": “JWT" }
• {
"token-type": "access-token",
"username": "snoopy",
"animal": "beagle",
"iss": "https://demo.superbiz.com/oauth2/token",
"scopes": [
“twitter”, "mans-best-friend"
],
"exp": 1474280963,
"iat": 1474279163,
"jti": "66881b068b249ad9"
}
• DTfSdMzIIsC0j8z3icRdYO1GaMGl6j1I_2DBjiiHW9vmDz8OAw8Jh8DpO32fv
0vICc0hb4F0QCD3KQnv8GVM73kSYaOEUwlW0k1TaElxc43_Ocxm1F5IUNZvzl
LJ_ksFXGDL_cuadhVDaiqmhct098ocefuv08TdzRxqYoEqYNo
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
Ligero pero con alto impacto en
la arquitectura
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
¿Qué tenemos hasta el
momento?
(repaso)
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
(LDAP)
Data completa
del usuario desde
ldap
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
(LDAP)
Generación de
Access Token
(pointer)
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
(LDAP)
Ambos se
insertan en
la BD
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
(LDAP)
Envío del Access Token (pointer)
hacia el cliente
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
Resultado final
cliente permanece
con el Pointer
Server almacena State
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
¿Qué podemos hacer ahora?
(Hello JWT!)
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
(LDAP)
Data completa
del usuario desde
ldap
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
(LDAP)
La data se
representa
en JSON
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
(LDAP)
JSON es firmado
RSA-SHA 256
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
(LDAP)
Se inserta
solamente el
pointer
en la DB
(para revocaciones)
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
(LDAP)
Envío del Access Token (estado)
hacia el cliente
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
Cliente permanece con State Server almacena el Pointer
Resultado obtenido
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
OAuth 2 - Password Grant
(LDAP)
(Token ID Store)
POST /oauth2/token
Host: api.superbiz.io
User-Agent: curl/7.43.0
Accept: */*
Content-Type: application/x-www-form-urlencoded
Content-Length: 54
grant_type=password&username=snoopy&password=woodstock
Verifica
Password
Genera
Token
Firmado
(Signed)
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
OAuth 2 - Password Grant
(LDAP)
(Token ID Store)
Verify
Password
Generate
Signed
Token
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
"access_token":"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.
eyJ0b2tlbi10eXBlIjoiYWNjZXNzLXRva2VuIiwidXNlcm5hb
WUiOiJzbm9vcHkiLCJhbmltYWwiOiJiZWFnbGUiLCJpc3M
iOiJodHRwczovL2RlbW8uc3VwZXJiaXouY29tL29hdXRoM
i90b2tlbiIsInNjb3BlcyI6WyJ0d2l0dGVyIiwibWFucy1iZXN0
LWZyaWVuZCJdLCJleHAiOjE0NzQyODA5NjMsImlhdCI6M
TQ3NDI3OTE2MywianRpIjoiNjY4ODFiMDY4YjI0OWFkOSJ
9.DTfSdMzIIsC0j8z3icRdYO1GaMGl6j1I_2DBjiiHW9vmDz8
OAw8Jh8DpO32fv0vICc0hb4F0QCD3KQnv8GVM73kSYaO
EUwlW0k1TaElxc43_Ocxm1F5IUNZvzlLJ_ksFXGDL_cuadh
VDaiqmhct098ocefuv08TdzRxqYoEqYNo",
"expires_in":3600,
"refresh_token":"eyJhbGctGzv3JOkF0XG5Qx2TlKWIAkF0X.
eyJ0b2tlbi10eXBlIjoiYWNjZXNzLXRva2VuIiwidXNlcm5hb
WUiOiJzbm9vcHkiLCJhbmltYWwiOiJiZWFnbGUiLCJpc3M
iOiJodHRwczovL",
}
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
Mensaje OAuth 2.0 con JWT
POST /painter/color/palette HTTP/1.1

Host: api.superbiz.io

Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbi10eXBlIjoiYWNjZXNzLXR
va2VuIiwidXNlcm5hbWUiOiJzbm9vcHkiLCJhbmltYWwiOiJiZWFnbGUiLCJpc3MiOiJodHRwczovL2RlbW8uc3VwZXJ
iaXouY29tL29hdXRoMi90b2tlbiIsInNjb3BlcyI6WyJ0d2l0dGVyIiwibWFucy1iZXN0LWZyaWVuZCJdLCJleHAiOjE0NzQy
ODA5NjMsImlhdCI6MTQ3NDI3OTE2MywianRpIjoiNjY4ODFiMDY4YjI0OWFkOSJ9.DTfSdMzIIsC0j8z3icRdYO1GaMGl
6j1I_2DBjiiHW9vmDz8OAw8Jh8DpO32fv0vICc0hb4F0QCD3KQnv8GVM73kSYaOEUwlW0k1TaElxc43_Ocxm1F5IUNZ
vzlLJ_ksFXGDL_cuadhVDaiqmhct098ocefuv08TdzRxqYoEqYNo
User-Agent: curl/7.43.0

Accept: */*

Content-Type: application/json

Content-Length: 46



{"color":{"b":0,"g":255,"r":0,"name":"green"}}
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018 OAuth 2 + JWT
Tokens enviados
3000 TPS
(HTTP+SSL)
0.55 TPS
(Verificaciones
refresh token)
OAuth 2
(LDAP)
4 saltos
12000 TPS
backend
3000 TPS
(signature verification)
12000 TPS
(signature verification)
Password enviados
(post oauth2/token …)
1000/daily
(HTTP+SSL)
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
“No!”
“Dame toda la
información del
salario de José.”
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
“Claro!”
“Dame toda la
información del
salario de José.”
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018 OAuth 2 + JWT
Valid
Tokens Sent
3000 TPS
(HTTP+SSL)
IP
whitelisting
0.55 TPS
(refresh token checks)
Password Sent
1000/daily
(HTTP+SSL)
(LDAP)
4 hops
12000 TPS
backend
9000 TPS
(signature verification)
12000 TPS
(signature verification)
Invalid
Tokens Sent
6000 TPS
(HTTP+SSL)
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
https://connect2id.com/products/nimbus-jose-jwt
Librería JWT
https://github.com/jwtk/jjwt
https://github.com/auth0/java-jwt
Demo
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
HTTP Signatures
(Amazon EC2 style API Security)
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
HTTP Signatures
• Ningún “secreto” toca el cable
• El firmar el mensaje completo
• Provee identidad
• Previene el compromiso o alteración del mensaje
• Soporta firmas Symmetric or Asymmetric
• IETF Draft
• https://tools.ietf.org/html/draft-cavage-http-signatures
• Extremadamente simple
• No eliminate el beneficio del JWT
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
Signature Message
POST /painter/color/palette HTTP/1.1

Host: api.superbiz.io

Authorization: Signature keyId=“El-Nombre-De-Mi-Llave”,
algorithm="hmac-sha256",
headers="content-length host date (request-target)”,
signature="j050ZC4iWDW40nVx2oVwBEymXzwvsgm+hKBkuw04b+w="

Date: Mon, 19 Sep 2016 16:51:35 PDT
Accept: */*

Content-Type: application/json

Content-Length: 46



{"color":{"b":0,"g":255,"r":0,"name":"green"}}
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
Signature closeup
Signature
keyId=“my-key-name",
algorithm="hmac-sha256",
headers="content-length host date (request-target)”,
signature="j050ZC4iWDW40nVx2oVwBEymXzwvsgm+hKBkuw04b+w=
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018 Signature Auth
Passwords enviados
0 TPS
(HTTP)
Signature (no auth)
3000 TPS
(LDAP o Keystore)
12000 TPS
(HTTP)
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018 Signature Auth
Signature Signature
3000 TPS
(LDAP o Keystore)
12000 TPS
(HTTP)
Passwords enviados
0 TPS
(HTTP)
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
“Hola, Larry!
Claro!”
Issue Returns
(bad)
“Dame toda la
información del
salario de José.”
Demo
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
OAuth 2.0 Con prueba de
posesión
(JWT + HTTP Signatures)
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
Key Value
Información de Identidad
(JWT)
Key ID
Prueba de identidad
(HTTP Signature)
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
{ "alg": “RS256", "typ": “JWT" }
{ "token-type": "access-token",
"username": "snoopy",
"iss": "https://demo.superbiz.com/oauth2/token",
"scopes": ["twitter”, "mans-best-friend"],
"exp": 1474280963,
"iat": 1474279163,
"jti": "66881b068b249ad9"
}
DTfSdMzIIsC0j8z3icRdYO1GaMGl6j1I_2DBjiiHW9vmDz8OAw8Jh8DpO32fv0vICc
0hb4F0QCD3KQnv8GVM73kSYaOEUwlW0k1TaElxc43_Ocxm1F5IUNZvzlLJ_ksF
XGDL_cuadhVDaiqmhct098ocefuv08TdzRxqYoEqYNo
Access Token
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
{ "alg": “RS256", "typ": “JWT" }
{ "token-type": "pop",
"cnf":{ "kid": "green-1234" }
"username": "snoopy",
"iss": "https://demo.superbiz.com/oauth2/token",
"scopes": ["twitter”, "mans-best-friend"],
"exp": 1474280963,
"iat": 1474279163,
"jti": "66881b068b249ad9"
}
DTfSdMzIIsC0j8z3icRdYO1GaMGl6j1I_2DBjiiHW9vmDz8OAw8Jh8DpO32fv0vICc
0hb4F0QCD3KQnv8GVM73kSYaOEUwlW0k1TaElxc43_Ocxm1F5IUNZvzlLJ_ksF
XGDL_cuadhVDaiqmhct098ocefuv08TdzRxqYoEqYNo
Access Token
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
OAuth 2 - Password Grant
(LDAP)
(Token ID Store)
POST /oauth2/token
Host: api.superbiz.io
User-Agent: curl/7.43.0
Accept: */*
Content-Type: application/x-www-form-urlencoded
Content-Length: 54
grant_type=password&username=snoopy&password=woodstock
Verifica
Password
Generate
Signed
Token
Genera
HMAC
Key
(Key Store)
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
OAuth 2 - Password Grant
(LDAP)
(Token ID Store)
Verifica
Password
Genera
Signed
Token
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
"access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc
3MiOiJodHRwczovL3NlcnZlci5leGFtcGxlLmNvbSIsImV4cCI6M
TMxMTI4MTk3MCwiaWF0IjoxMzExMjgwOTcwLCJjbmYiOnsia2",
"token_type":"pop",
"expires_in":3600,
"refresh_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc
3MiOiJodHRwczovL2FzZGZhc2RzZGZzZXJ2ZXIuZXhhbXBsZS5
jb20iLCJleHAiOjEzMTEyODE5NzAsImlhdCI6MTMxMTI4MDk3M",
"key":"eyJrdHkiOiJvY3QiLCJ1c2UiOiJzaWciLCJraWQiOiJvcmFuZ
2UteXlqOUQwZWgiLCJrIjoiVlotMFFHTFoyUF9SUFVTVzEwQ0l1
MFdNeVhxLU5EMnBtRFl6QTBPVEtXVEhscDVpYWM1SzRWZWlS
ci1fQk9vWEo0WDJmU1R0NG5Id29fcXV0YTdqSkpLVDRQRVd5W
WFuQlNGc2kwRFc3b3dULUhFeEFHRHlKdEhVdE53NXhzczhOajZ
PeE5QdjZyUk9FLWtldmhMMndCOWNxZ2RJc2NidkRocmFzMzljd
2ZzIiwiYWxnIjoiSFMyNTYifQ"
}
Genera
HMAC
Key
(Key Store)
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
JSON Web Key (encoded)
eyJrdHkiOiJvY3QiLCJ1c2UiOiJzaWciLCJraWQiOiJvcmFuZ2Ut
eXlqOUQwZWgiLCJrIjoiVlotMFFHTFoyUF9SUFVTVzEwQ0l1M
FdNeVhxLU5EMnBtRFl6QTBPVEtXVEhscDVpYWM1SzRWZ
WlSci1fQk9vWEo0WDJmU1R0NG5Id29fcXV0YTdqSkpLVDRQ
RVd5WWFuQlNGc2kwRFc3b3dULUhFeEFHRHlKdEhVdE53N
XhzczhOajZPeE5QdjZyUk9FLWtldmhMMndCOWNxZ2RJc2Nid
kRocmFzMzljd2ZzIiwiYWxnIjoiSFMyNTYifQ
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
JSON Web Key (decoded)
{ "kty": "oct",
"use": "sig",
"kid": "orange-1234",
"k": "VZ-0QGLZ2P_RPUSW10CIu0WMyXq-ND2pmDYzA0OTKW
THlp5iac5K4VeiRr-_BOoXJ4X2fSTt4nHwo_quta7j
JJKT4PEWyYanBSFsi0DW7owT-HExAGDyJtHUtNw5xs
s8Nj6OxNPv6rROE-kevhL2wB9cqgdIscbvDhras39c
wfs",
"alg": "HS256"
}
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
Signed OAuth 2.0 Message
POST /painter/color/palette HTTP/1.1

Host: api.superbiz.io

Authorization: Signature keyId=“orange-1234", algorithm="hmac-sha256",
headers="content-length host date (request-target)”,
signature="j050ZC4iWDW40nVx2oVwBEymXzwvsgm+hKBkuw04b+w="
Bearer:
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbi10eXBlIjoiYWNjZXNzLXRva2VuIiwidXNlcm5h
bWUiOiJzbm9vcHkiLCJhbmltYWwiOiJiZWFnbGUiLCJpc3MiOiJodHRwczovL2RlbW8uc3VwZXJiaXouY29t
L2
9hdXRoMi90b2tlbiIsInNjb3BlcyI6WyJ0d2l0dGVyIiwibWFucy1iZXN0LWZyaWVuZCJdLCJleHAiOjE0NzQyO
DA5NjMsImlhdCI6MTQ3NDI3OTE2MywianRpIjoiNjY4ODFiMDY4YjI0OWFkOSJ9.DTfSdMzIIsC0j8z3icRdY
O1GMGl6j1I_2DBjiiHW9vmDz8OAw8Jh8DpO32fv0vICc0hb4F0QCD3KQnv8GVM73kSYaOEUwlW0k1TaEl
xc43_Ocxm1F5IUNZvzlLJ_ksFXGDL_cuadhVDaiqmhct098ocefuv08TdzRxqYoEqYNo

Date: Mon, 19 Sep 2016 16:51:35 PDT
Accept: */*

Content-Type: application/json

Content-Length: 46



{"color":{"b":0,"g":255,"r":0,"name":"green"}}
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018 OAuth 2 + JWT +
Tokens Sent
3000 TPS
(HTTP+SSL)
0.55 TPS
(refresh token checks)
Password Sent
1000/daily
(HTTP+SSL)
OAuth 2
(LDAP)
4 hops
12000 TPS
backend
3000 TPS
(signature verification)
12000 TPS
(signature verification)
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
https://tools.ietf.org/html/draft-ietf-oauth-pop-key-distribution
Specification Reference
#RESTSecurity @CesarHgt @tomitribe
EcuadorJUG2018
Observations
• HTTP Signatures the only HTTP friendly approach
• Signatures does not solve the “Identity Load” problem
• OAuth 2 with JWT significantly improves IDP load
• Plain OAuth 2
• HTTP Session-like implications
• OAuth 2 with JWT
• Signed cookie
• Signing key to the future
Gracias
Diapositivas y Gateway Sign-up
https://tribestream.io/ecuadorjug/
#RESTSecurity
Ecuador JUG

2018 ecuador deconstruyendo y evolucionando la seguridad en servicios rest