Slide 1

Slide 1 text

PROTECTING YOUR API
 THE PAST, THE PRESENT AND THE FUTURE ARMEN MKRTCHYAN

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

ARMEN MKRTCHYAN @IAMTANKIST (github, twitter, telegram)

Slide 4

Slide 4 text

YOU CAN WRITE A LOT OF TEXT ON BLACK BACKGROUND HERE.

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

osmihelp.org

Slide 7

Slide 7 text

PROTECTING YOUR API
 THE PAST, THE PRESENT AND THE FUTURE ARMEN MKRTCHYAN

Slide 8

Slide 8 text

AUTH CODE REFRESH_TOKEN ACCESS_TOKEN API KEY BEARER TOKEN ID_TOKEN

Slide 9

Slide 9 text

AUTH CODE REFRESH_TOKEN ACCESS_TOKEN API KEY BEARER TOKEN ID_TOKEN TOKEN?

Slide 10

Slide 10 text

TOKEN WILLIAMS Aliases Blackie Gender Male Hair Black Age 10 Occupation Student Grade 4th Grade

Slide 11

Slide 11 text

noun to·ken \ ˈtō-kən \ TOKEN „something given or shown as a guarantee (as of authority, right, or identity)“

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

HTTP BASIC AUTH

Slide 14

Slide 14 text

$ sudo htpasswd -c /etc/apache2/.htpasswd user1 $ cat /etc/apache2/.htpasswd user1:$apr1$/woC1jnP$KAh0SsVn5qeSMjTtn0E9Q0 STEP 1

Slide 15

Slide 15 text

STEP 2 - NGINX CONFIGURATION ... http { server { location /foo/bar { auth_basic "Protected Area"; auth_basic_user_file /etc/apache2/.htpasswd; } } } ...

Slide 16

Slide 16 text

STEP 3 - USE Access url in the browser - fill in the dialog base64_encode('user:password') => d3BhbG1lcjp0ZXN0dGVzdA== GET / HTTP/1.1
 Host: example.com
 Authorization: Basic d3BhbG1lcjp0ZXN0dGVzdA== // embed in URL
 https://user:[email protected] 2 1 3

Slide 17

Slide 17 text

STEP 3 - USE Access url in the browser - fill in the dialog base64_encode('user:password') => d3BhbG1lcjp0ZXN0dGVzdA== GET / HTTP/1.1
 Host: example.com
 Authorization: Basic d3BhbG1lcjp0ZXN0dGVzdA== // embed in URL
 https://user:[email protected] 2 1 3

Slide 18

Slide 18 text

OAUTH 1

Slide 19

Slide 19 text

STEP 1 - INITIALISE POST /initiate HTTP/1.1
 Host: photos.example.net
 Authorization: OAuth realm="Photos", \
 oauth_consumer_key="dpf43f3p2l4k3l03", \
 oauth_signature_method="HMAC-SHA1", \
 oauth_timestamp="137131200", \
 oauth_nonce="wIjqoS", \
 oauth_callback="http%3A%2F%2Fclient.example.com%2Fready", \
 oauth_signature="74KNZJeDHnMBp0EMJ9ZHt%2FXKycU%3D" \ HTTP/1.1 200 OK
 Content-Type: application/x-www-form-urlencoded
 oauth_token=hh5s93j4hdidpola&
 oauth_token_secret=hdhd0244k9j7ao03&
 oauth_callback_confirmed=true

Slide 20

Slide 20 text

STEP 1 - INITIALISE POST /initiate HTTP/1.1
 Host: photos.example.net
 Authorization: OAuth realm="Photos", \
 oauth_consumer_key="dpf43f3p2l4k3l03", \
 oauth_signature_method="HMAC-SHA1", \
 oauth_timestamp="137131200", \
 oauth_nonce="wIjqoS", \
 oauth_callback="http%3A%2F%2Fclient.example.com%2Fready", \
 oauth_signature="74KNZJeDHnMBp0EMJ9ZHt%2FXKycU%3D" \ HTTP/1.1 200 OK
 Content-Type: application/x-www-form-urlencoded
 oauth_token=hh5s93j4hdidpola&
 oauth_token_secret=hdhd0244k9j7ao03&
 oauth_callback_confirmed=true

Slide 21

Slide 21 text

STEP 2 - AUTHORIZATION GET /authorize?oauth_token=hh5s93j4hdidpola HTTP/1.1
 Host: photos.example.net // Asks for username and login and redirects to http://? \
 oauth_token=hh5s93j4hdidpola& \
 oauth_verifier=hfdp7dh39dks9884

Slide 22

Slide 22 text

STEP 3 - TOKEN POST /token HTTP/1.1 Host: photos.example.net Authorization: OAuth realm="Photos", oauth_consumer_key="dpf43f3p2l4k3l03", \ oauth_token="hh5s93j4hdidpola", \ oauth_signature_method="HMAC-SHA1", \ oauth_timestamp="137131201", \ oauth_nonce="walatlh", \ oauth_verifier="hfdp7dh39dks9884", \ oauth_signature="gKgrFCywp7rO0OXSjdot%2FIHF7IU%3D" // redirects back with to http://? \ oauth_token=hh5s93j4hdidpola& \ oauth_verifier=hfdp7dh39dks9884

Slide 23

Slide 23 text

STEP 4 - USING TOKEN GET /photos?file=vacation.jpg&size=original HTTP/1.1 Host: photos.example.net Authorization: OAuth realm="Photos", oauth_consumer_key="dpf43f3p2l4k3l03", oauth_token="nnch734d00sl2jdk", oauth_signature_method="HMAC-SHA1", oauth_timestamp="137131202", oauth_nonce="chapoH", oauth_signature="MdpQcU8iPSUjWoN%2FUDMsK2sui9I%3D"

Slide 24

Slide 24 text

OAUTH 2

Slide 25

Slide 25 text

• More OAuth Flows • No client-side cryptography • Expiration of access_tokens

Slide 26

Slide 26 text

CLIENTS SERVICE Users Admins Services 3rd-Party Services Monitoring Things

Slide 27

Slide 27 text

LETS TALK ABOUT LEGS!

Slide 28

Slide 28 text

No content

Slide 29

Slide 29 text

2-LEGGED/3-LEGGED AUTHENTICATION

Slide 30

Slide 30 text

No content

Slide 31

Slide 31 text

No content

Slide 32

Slide 32 text

3-LEGGED 2-LEGGED SERVICE Users Admins Services 3rd-Party Services Monitoring Things

Slide 33

Slide 33 text

CLIENT_ID CLIENT_SECRET REDIRECT_URI GRANT_TYPES SCOPES CLIENT

Slide 34

Slide 34 text

AUTHORIZATION CODE CLIENT CREDENTIALS PASSWORD IMPLICIT REFRESH CUSTOM GRANT TYPES ACCESS_TOKEN

Slide 35

Slide 35 text

AUTHORIZATION CODE 3-LEGGED

Slide 36

Slide 36 text

AUTHORIZAION CODE - STEP 1 POST /authorize HTTP/1.1 Host: photos.example.net Content-Type: application/x-www-form-urlencoded response_type=code& \ client_id=CLIENT_ID& \ redirect_uri=https://client.example.com/cb& \ scope=email,birthday& \ state=csrf_string // Asks for user authorisation and redirects back HTTP/1.1 302 Found Location: https://client.example.com/cb?code=CODE&state=csrf_string

Slide 37

Slide 37 text

AUTHORIZAION CODE - STEP 2 POST /token HTTP/1.1 Host: photos.example.net Content-Type: application/x-www-form-urlencoded grant_type=authorization_code& \ code=CODE& \ redirect_uri=https://client.example.com/cb& \ client_id=CLIENT_id& Content-Type: application/json;charset=UTF-8 { "access_token":"2YotnFZFEjr1zCsicMWpAA", "expires_in":3600, "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA" }

Slide 38

Slide 38 text

CLIENT CREDENTIALS 2-LEGGED

Slide 39

Slide 39 text

POST /token HTTP/1.1 Host: photos.example.net Content-Type: application/x-www-form-urlencoded grant_type=client_credentials& \ client_id=CLIENT_id& \ client_secret=CLIENT_SECRET Content-Type: application/json;charset=UTF-8 { "access_token":"2YotnFZFEjr1zCsicMWpAB", "expires_in":3600 }

Slide 40

Slide 40 text

USING ACCESS_TOKEN

Slide 41

Slide 41 text

GET /photos HTTP/1.1 Host: photos.example.net Authorization: Bearer 2YotnFZFEjr1zCsicMWpAB

Slide 42

Slide 42 text

GET /photos HTTP/1.1 Host: photos.example.net Authorization: Bearer 2YotnFZFEjr1zCsicMWpAB

Slide 43

Slide 43 text

SELF-INVENTED SOLUTIONS

Slide 44

Slide 44 text

No content

Slide 45

Slide 45 text

JWT

Slide 46

Slide 46 text

No content

Slide 47

Slide 47 text

• ISS - ISSUER (AKA ORIGIN) • SUB - SUBJECT (AKA USER_ID) • AUD - AUDIENCE (AKA CLIENT_ID) • EXP - EXPIRES AT • IAT - ISSUED AT JWT STANDARD CLAIMS

Slide 48

Slide 48 text

No content

Slide 49

Slide 49 text

lexik/LexikJWTAuthenticationBundle POST /users/login?_username=...&_password=... HTTP/1.1 {token: "eyJhbGciOiJ..."} POST /photos HTTP/1.1 Authorization: Bearer eyJhbGciOiJ...

Slide 50

Slide 50 text

lexik/LexikJWTAuthenticationBundle POST /users/login?_username=...&_password=... HTTP/1.1 {token: "eyJhbGciOiJ..."} POST /photos HTTP/1.1 Authorization: Bearer eyJhbGciOiJ...

Slide 51

Slide 51 text

RETROSPECTIVE

Slide 52

Slide 52 text

BASIC AUTH - NICE, PASS INVOLVED OAUTH1 - TOO COMPLEX OAUTH2 - SOLVES THE PROBLEM, BUT... SELF-INVENTED - NO* JWT - OVER-SIMPLISTIC *unless you really know what you are doing

Slide 53

Slide 53 text

37signals, Asana, Amazon, Auth0, Azure, Bitbucket, Bitly, BufferApp, Clever, DeviantArt, Discogs, Disqus, Dropbox, EVE Online, Eventbrite, Facebook, FI-WARE, Flickr, Foursquare, GitHub, GitLab, Google, Hubic, Instagram, itembase, Jira, Linkedin, Mail.ru, Odnoklassniki, PayPal, QQ, Reddit, Salesforce, SensioLabs Connect, Sina Weibo, Spotify, Soundcloud, Stack Exchange, Stereomood, Strava, Toshl, Trello, Twitch, Twitter, Wunderlist, Vkontakte, Windows Live, XING, Yahoo, Yandex HTTPS://GITHUB.COM/HWI/ HWIOAUTHBUNDLE

Slide 54

Slide 54 text

OPENID CONNECT

Slide 55

Slide 55 text

OAUTH2 + IDENTITY LAYER

Slide 56

Slide 56 text

OAUTH2 + IDENTITY LAYER DISCOVERY DYNAMIC CLIENT REGISTRATION IMPLEMENTATION CERTIFICATION ID_TOKEN STANDARD CLAIMS SESSION MANAGEMENT JWKS FORM POST RESPONSE MODE

Slide 57

Slide 57 text

No content

Slide 58

Slide 58 text

No content

Slide 59

Slide 59 text

AUTH0 DEUTSCHE TELEKOM GOOGLE MICROSOFT PAYPAL PRO7SAT1 RED HAT SALESFORCE SYMANTEC VERIZON

Slide 60

Slide 60 text

WHAT CHANGED?

Slide 61

Slide 61 text

AUTHORIZAION CODE - STEP 1 POST /authorize HTTP/1.1 Host: photos.example.net Content-Type: application/x-www-form-urlencoded response_type=code& \ client_id=CLIENT_ID& \ redirect_uri=https://client.example.com/cb& \ scope=email,birthday,openid& \ state=csrf_string // Asks for user authorisation and redirects back HTTP/1.1 302 Found Location: https://client.example.com/cb?code=CODE&state=csrf_string

Slide 62

Slide 62 text

No content

Slide 63

Slide 63 text

{ "access_token": "SlAV3...2hkKG", "token_type": "Bearer", "refresh_token": "8xLO...xBtZp8", "expires_in": 3600, "id_token": "eyJhbGci...OiJS.UzI1...ImtpZCI6.IjFlOWdkaz...cifQewo" }

Slide 64

Slide 64 text

{ "iss": "http://server.example.com", "sub": "248289761001", // aka user_id "aud": "s6BhdRkqt3", // aka client_id "nonce": "n-0S6_WzA2Mj", // aka CSRF token "exp": 1311281970, "iat": 1311280970 }

Slide 65

Slide 65 text

USERINFO ENDPOINT

Slide 66

Slide 66 text

GET /userinfo HTTP/1.1 Authorization: Bearer SlAV3...2hkKG { "sub": "248289761001", "name": "Jane Doe", "given_name": "Jane", "family_name": "Doe", "preferred_username": "j.doe", "email": "[email protected]", "picture": "http://example.com/janedoe/me.jpg" } IT'S A STANDARD!!! (SECTION 5.2)

Slide 67

Slide 67 text

GET /userinfo HTTP/1.1 Authorization: Bearer SlAV3...2hkKG { "sub": "248289761001", "name": "Jane Doe", "given_name": "Jane", "family_name": "Doe", "preferred_username": "j.doe", "email": "[email protected]", "picture": "http://example.com/janedoe/me.jpg" }

Slide 68

Slide 68 text

DISCOVERY

Slide 69

Slide 69 text

GET /.well-known/openid-configuration HTTP/1.1 Host: accounts.google.com Authorization: Bearer SlAV3...2hkKG { "issuer": "https://accounts.google.com", "authorization_endpoint": "https://accounts.google.com/o/oauth2/v2/auth", "token_endpoint": "https://www.googleapis.com/oauth2/v4/token", "userinfo_endpoint": "https://www.googleapis.com/oauth2/v3/userinfo", "revocation_endpoint": "https://accounts.google.com/o/oauth2/revoke", "jwks_uri": "https://www.googleapis.com/oauth2/v3/certs", "response_types_supported": [ "code", "token", "id_token", "code token", "code id_token", "token id_token", "code token id_token", "none" ], "scopes_supported": [ "openid", "email", "profile" ], "claims_supported": [ "aud", "email", "email_verified", "exp", "family_name", "given_name", "iat", "iss", "locale", "name", "picture", "sub" ] }

Slide 70

Slide 70 text

ARE WE THERE YET?

Slide 71

Slide 71 text

No content

Slide 72

Slide 72 text

EVERY TALK SHOULD DELIVER A MESSAGE

Slide 73

Slide 73 text

„I might be no body, but wait ‘til I’m together like a symphony.“ – IMMORTAL TECHNIQUE – “THE PROPHECY”

Slide 74

Slide 74 text

THANK YOU! PLEASE GIVE ME SOME FEEDBACK! @IAMTANKIST (github, twitter, telegram)