Slide 1

Slide 1 text

Securing Your APIs with OAuth 2.0 AARON PARECKI @aaronpk aaronpk.com

Slide 2

Slide 2 text

Specs are not good tutorials!

Slide 3

Slide 3 text

RFC6749 RFC6750 CLIENT TYPE AUTH METHOD GRANT TYPE RFC6819 RFC7009 RFC7592 RFC7662 RFC7636 RFC7591 RFC7519 BUILDING YOUR APPLICATION RFC8252 OIDC RFC8414 STATE PARAM TLS CSRF UMA 2 FAPI RFC7515 RFC7516 RFC7517 RFC7518 TOKEN BINDING POP SECURITY BCP CIBA HTTP SIGNING MUTUAL TLS SPA BCP JARM JAR TOKEN EXCHANGE DPOP

Slide 4

Slide 4 text

@aaronpk THE PASSWORD ANTI-PATTERN

Slide 5

Slide 5 text

@aaronpk THE PASSWORD ANTI-PATTERN facebook.com ~2010

Slide 6

Slide 6 text

@aaronpk

Slide 7

Slide 7 text

@aaronpk so... how can I let an app access my data without giving it my password?

Slide 8

Slide 8 text

@aaronpk An open standard for authorization

Slide 9

Slide 9 text

@aaronpk https://yelp.com/

Slide 10

Slide 10 text

but… OAuth doesn’t tell the app who logged in

Slide 11

Slide 11 text

No content

Slide 12

Slide 12 text

@aaronpk A HOTEL KEY CARD, FOR APPS Authorization Server Access Token Resource Server (API)

Slide 13

Slide 13 text

Authentication Authorization provides user identity provides delegated access

Slide 14

Slide 14 text

@aaronpk https://gmail.com

Slide 15

Slide 15 text

@aaronpk https://accounts.google.com/oauth/authorize?response_ty

Slide 16

Slide 16 text

@aaronpk https://accounts.google.com/oauth/authorize?response_ty

Slide 17

Slide 17 text

@aaronpk https://accounts.google.com/oauth/authorize?response_ty

Slide 18

Slide 18 text

@aaronpk https://gmail.com

Slide 19

Slide 19 text

@aaronpk HOW OAUTH WORKS

Slide 20

Slide 20 text

@aaronpk OBTAINING AN ACCESS TOKEN Applications use an OAuth flow to obtain an access token ▸ Authorization Code Flow: web apps, native apps ▸ Device Flow: browserless or input-constrained devices ▸ Password: not really OAuth, only for first-party apps ▸ Client Credentials: for machine-to-machine authentication

Slide 21

Slide 21 text

@aaronpk POST /resource/1/update HTTP/1.1 Authorization: Bearer RsT5OjbzRn430zqMLgV3Ia Host: api.authorization-server.com description=Hello+World USING AN ACCESS TOKEN

Slide 22

Slide 22 text

@aaronpk ROLES IN OAUTH OAuth Server (Authorization Server) aka the token factory API (Resource Server) The Application (Client) The User (Resource Owner) Device (User Agent)

Slide 23

Slide 23 text

AUTHORIZATION CODE GRANT TYPE:

Slide 24

Slide 24 text

User: I’d like to use this great app App: Please go to the authorization server to grant me access User: I’d like to log in to “Yelp”, it wants to access my contacts AS: Here is a temporary code the app can use App: Here is the temporary code, and my secret, please give me a token User: Here is the temporary code, please use this to get a token AS: Here is an access token! App: Please let me access this user’s data with this access token! User Agent App OAuth Server API ?

Slide 25

Slide 25 text

Front Channel Back Channel https://accounts.google.com/?... Passing data via the browser's address bar The user, or malicious software, can modify the requests and responses Sent from client to server HTTPS request from client to server, so requests cannot be tampered with

Slide 26

Slide 26 text

Back Channel Benefits ‣ The application knows it's talking to the right server ‣ Connection from app to server can't be tampered with ‣ Response from the server can be trusted because it came back in the same connection

Slide 27

Slide 27 text

OAuth Server OAuth Client Passing Data via the Back Channel

Slide 28

Slide 28 text

OAuth Server OAuth Client Passing Data via the Front Channel

Slide 29

Slide 29 text

Front Channel Benefits https://accounts.google.com/?... ‣ Lets the server prompt the user for additional auth factors without the client involved ‣ The user being involved enables them to give consent ‣ Doesn't require the receiver to have a publicly routable IP
 (e.g. can work on a phone)

Slide 30

Slide 30 text

The app builds the auth link https://authorization-server.com/auth • response_type=code - indicates that your app expects to receive an authorization code • client_id=CLIENT_ID - The client ID you received when you first created the application • redirect_uri=REDIRECT_URI - Indicates the URL to return the user to after authorization is complete, such as https://example-app.com/callback • scope=contacts - A space-separated string indicating which parts of the user's account you wish to access • state=1234zyx - A random string generated by your application, which you'll verify later Front Channel

Slide 31

Slide 31 text

The app builds the auth link https://authorization-server.com/auth? response_type=code& client_id=CLIENT_ID& redirect_uri=REDIRECT_URI& scope=contacts& state=1234zyx Front Channel

Slide 32

Slide 32 text

Front Channel

Slide 33

Slide 33 text

The user is redirected back to the application with an authorization code https://example.com/callback?error=access_denied&state=1234xyz The user is redirected back to the application with an error code If User Denies If User Allows https://example.com/callback? code=AUTH_CODE_HERE& state=1234zyx Front Channel

Slide 34

Slide 34 text

Verify State • The application verifies the state matches the value it started with • This lets the application have more confidence that it isn't trying to exchange an attacker's authorization code The app must do this because it received the authorization code via the front channel! Front Channel

Slide 35

Slide 35 text

Exchange the Code for an Access Token POST https://api.authorization-server.com/token • grant_type=authorization_code - indicates that this request contains an authorization code • code=CODE_FROM_QUERY - Include the authorization code from the query string of this request • redirect_uri=REDIRECT_URI - This must match the redirect_uri used in the original request • client_id=CLIENT_ID - The client ID you received when you first created the application • client_secret=CLIENT_SECRET - Since this request is made from server-side code, the secret is included Back Channel

Slide 36

Slide 36 text

Exchange the Code for an Access Token POST https://api.authorization-server.com/token Content-type: application/x-www-form-urlencoded grant_type=authorization_code& code=AUTH_CODE_HERE& redirect_uri=REDIRECT_URI& client_id=CLIENT_ID& client_secret=CLIENT_SECRET Back Channel

Slide 37

Slide 37 text

Exchange the Code for an Access Token { "access_token":"RsT5OjbzRn430zqMLgV3Ia", "expires_in":3600, "refresh_token":"64d049f8b21191e12522d5d96d5641af5e8" } The server replies with an access token and expiration time or if there was an error: {"error":"invalid_request"} Back Channel

Slide 38

Slide 38 text

Public Clients Confidential Clients Application running on a server Has the ability to keep strings secret since code is running in a trusted environment The application can't keep strings secret JavaScript/Single-Page apps: "view source" Native apps: decompile and extract strings

Slide 39

Slide 39 text

Problem: • The authorization server returns the authorization code in the front channel • so it can't guarantee it was actually received by the correct application • it needs a way to verify that the correct application is using it to get a token • Normally the client_secret solves this, but we can't use a secret!

Slide 40

Slide 40 text

@aaronpk PKCE PROOF-KEY FOR CODE EXCHANGE RFC 7636 (pronounced "pixie")

Slide 41

Slide 41 text

User: I’d like to use this great app App: Please go to the authorization server to grant me access, take this hash with you User: I’d like to log in to this app, here's the hashed secret it gave me AS: Here is a temporary code the app can use App: Here's the code, and the plaintext secret, please give me a token User: Here is the temporary code, please use this to get a token AS: Let me verify the hash of that secret... ok here is an access token! App: Please let me access this user’s data with this access token! App: Hang on while I generate a new secret and hash it User Agent App OAuth Server API ?

Slide 42

Slide 42 text

OAuth Server (Authorization Server) aka the token factory API (Resource Server) The Application (Client) The User's Device (User Agent)

Slide 43

Slide 43 text

OAuth Server (Authorization Server) aka the token factory API (Resource Server) The Application (Client) The User's Device (User Agent)

Slide 44

Slide 44 text

SCOPE

Slide 45

Slide 45 text

https://accounts.google.com/oauth/authorize?response_type

Slide 46

Slide 46 text

https://arstechnica.com/information-technology/2017/05/dont-trust-oauth-why-the-google-docs-worm-was-so-convincing/

Slide 47

Slide 47 text

No content

Slide 48

Slide 48 text

No content

Slide 49

Slide 49 text

No content

Slide 50

Slide 50 text

No content

Slide 51

Slide 51 text

No content

Slide 52

Slide 52 text

No content

Slide 53

Slide 53 text

No content

Slide 54

Slide 54 text

No content

Slide 55

Slide 55 text

No content

Slide 56

Slide 56 text

No content

Slide 57

Slide 57 text

Scope • Allows an application to request a limited-capability access token • Limits what an access token can do within what a user is already allowed to do • Is not a way to build a permissions system

Slide 58

Slide 58 text

ACCESS TOKENS

Slide 59

Slide 59 text

Types of Access Tokens MTQ0NjJkZmQ5OTM2NDE1ZTZjNGZmZjI3 eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjEwMDAsI mlzcyI6Imh0dHBzOi8vYXV0aG9yaXphdGlvbi1zZXJ2ZXIuY29tIiw iY2lkIjoiaHR0cHM6Ly9leGFtcGxlLWFwcC5jb20iLCJpYXQiOjE0N zAwMDI3MDMsImV4cCI6MTUyOTE3NDg1MSwic2NvcGUiOiJyZWFkIHd yaXRlIn0.QiIrnmaC4VrbAYAsu0YPeuJ992p20fSxrXWPLw-gkFA Reference Self-Encoded (e.g. JWT)

Slide 60

Slide 60 text

Reference Tokens MTQ0NjJkZmQ5OTM2NDE1ZTZjNGZmZjI3 * user_id * expiration * permissions * ...

Slide 61

Slide 61 text

Self-Encoded Tokens eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjEwMDAsI mlzcyI6Imh0dHBzOi8vYXV0aG9yaXphdGlvbi1zZXJ2ZXIuY29tIiw iY2lkIjoiaHR0cHM6Ly9leGFtcGxlLWFwcC5jb20iLCJpYXQiOjE0N zAwMDI3MDMsImV4cCI6MTUyOTE3NDg1MSwic2NvcGUiOiJyZWFkIHd yaXRlIn0.QiIrnmaC4VrbAYAsu0YPeuJ992p20fSxrXWPLw-gkFA { "sub": "{USER_ID}", "aud": "{CLIENT_ID}", "exp": 1524240821, "scope": "create" }

Slide 62

Slide 62 text

are you building an app? are you building an API? Authorization: Bearer RsT5OjbzRn430zqMLgV3Ia just use the token parse/extract/introspect the token { "sub": "{USER_ID}", "aud": "{CLIENT_ID}", "exp": 1524240821, "scp": "create" }

Slide 63

Slide 63 text

only the API should try to understand
 access tokens

Slide 64

Slide 64 text

Types of Access Tokens MTQ0NjJkZmQ5OTM2NDE1ZTZjNGZmZjI3 eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjEwMDAsI mlzcyI6Imh0dHBzOi8vYXV0aG9yaXphdGlvbi1zZXJ2ZXIuY29tIiw iY2lkIjoiaHR0cHM6Ly9leGFtcGxlLWFwcC5jb20iLCJpYXQiOjE0N zAwMDI3MDMsImV4cCI6MTUyOTE3NDg1MSwic2NvcGUiOiJyZWFkIHd yaXRlIn0.QiIrnmaC4VrbAYAsu0YPeuJ992p20fSxrXWPLw-gkFA Reference Self-Encoded (e.g. JWT)

Slide 65

Slide 65 text

Pros • Can be revoked by deleting from the database • Can easily show a list of active tokens to the user Reference Tokens Cons • Requires storing all active tokens • API must check the validity with either a DB lookup or HTTP request Best for • Small scale APIs with an integrated OAuth server

Slide 66

Slide 66 text

Pros • Requires no storage • Better separation of concerns (no shared storage between authorization server and API) • Can be validated at the API without a DB/HTTP lookup Self-Encoded Tokens Cons • Cannot be revoked without storing additional information • Cannot get a list of all active tokens Best for • Large-scale distributed architectures, and using an external OAuth server

Slide 67

Slide 67 text

A JWT Access Token eyJraWQiOiJvQ1JjR3RxVDhRV2tJR0MyVXpmcEZUczVqSkdnM00zSTNOMHgtZDJhSFNNIiwiYWxn IjoiUlMyNTYifQ.eyJ2ZXIiOjEsImp0aSI6IkFULkp3eVRTcTlqNDU0bDNTNmRTM1VTV1hMVVpwe kdKdWNSd1ZEbFZCNWNIc3cuVVM1V1NGYVFiQllUMC9GM2tjMG8vK1ZUY3VZZzdwVnZqZXZTT3hkU HhCMD0iLCJpc3MiOiJodHRwczovL2Rldi0zOTYzNDMub2t0YXByZXZpZXcuY29tL29hdXRoMi9kZ WZhdWx0IiwiYXVkIjoiYXBpOi8vZGVmYXVsdCIsImlhdCI6MTU0MzgwMzAyNSwiZXhwIjoxNTQzO DA2NjI1LCJjaWQiOiIwb2FoenBwM3RjcEZyZmNXSTBoNyIsInVpZCI6IjAwdWkwZmpraWV5TDQ2b WEwMGg3Iiwic2NwIjpbIm9mZmxpbmVfYWNjZXNzIiwicGhvdG8iXSwic3ViIjoiaW5xdWlzaXRpd mUtYWxiYXRyb3NzQGV4YW1wbGUuY29tIn0.ncVkzcc6qrFJSXE3-5UsRu_kHvbwIMKYL3PFaMwRe YTquPAcOQ8t93xF0bxbS8wrP0udCDvk6eYq4VbjoFdD59Yy6ltz0OKQl3- g8uFg2RwqTBMOKR0mYtQH0RCr9ORhSsmKolaDDt4TcRX78ZOAyhZ_Qg_UcEoHM4uZikpzBJYpYKb CCfbx-6FzYyHuvevSFzURISYpSHv3nbzirkEzKbOv7eZlg1cCYBdUoGuVBskyHxfMxFpoKQU3mwI FdlQJR8LZ8hA_5ZdYjjMeSXfjnhlP2rppJiHy1NreGXXcUsUA74V2t_keY44deTrnPgoFOSe9Ich Wqcj6sDMDutC4ag

Slide 68

Slide 68 text

A JWT Access Token { "typ": "JWT", "alg": "RS256", "kid": "oCRcGtqT8QWkIGC2UzfpFTs5jJGg3M3I3N0x-d2aHSM" } { "ver": 1, "jti": "AT.JwyTSq9j454l3S6dS3USWXLUZpzGJucRwVDlVB5cHsw.US5WSFaQbBYT0/F3kc0o/+VTcuYg7pVvjevSOxdPxB0=", "iss": "https://dev-396343.oktapreview.com/oauth2/default", "aud": "api://default", "iat": 1543803025, "exp": 1543806625, "cid": "0oahzpp3tcpFrfcWI0h7", "uid": "00ui0fjkieyL46ma00h7", "scp": [ "offline_access", "photo" ], "sub": "inquisitive-albatross@example.com" } header claims

Slide 69

Slide 69 text

No content

Slide 70

Slide 70 text

No content

Slide 71

Slide 71 text

Libraries!

Slide 72

Slide 72 text

Access Token Validation The Fast Way The Strong Way Inspect the JWT Check the expiration timestamp Validate the cryptographic signature Check the token at the introspection endpoint eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZS I6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImp0aSI6ImI5ZDRhNzViLTA2MDMtNDgxYy1hM jgyLTY3YTk0NDJiNGRkNiIsImlhdCI6MTUzMjQwMDkyMiwiZXhwIjoxNTMyNDA0NTIyfQ.S jYROEt8lZpEOq1eKh3OxRmRk3xttOXZeD5yW8aW2k8 { "sub": "1234567890", "name": "John Doe", "admin": true, "jti": "b9d4a75b-0603-481c-a282-67a9442b4dd6", "iat": 1532400922, "exp": 1532404522 } POST https://authorization-server.com/introspect token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3OD &client_id={CLIENT_ID} &client_secret={CLIENT_SECRET}

Slide 73

Slide 73 text

Rejecting Revoked Tokens 1:00 2:00 3:00 4:00 5:00 6:00 7:00 expired 0:00 Local Validation Remote Introspection User revokes application

Slide 74

Slide 74 text

API Gateway Token Validation API Gateway CUSTOMER API BILLING API ORDER API LOCAL VALIDATION TOKEN INTROSPECTION

Slide 75

Slide 75 text

How long should access tokens last?

Slide 76

Slide 76 text

@aaronpk DIFFERENT LIFETIMES FOR DIFFERENT USERS/SCOPES ACCESS TOKEN 1 HOUR REFRESH TOKEN 24 HOURS ACCESS TOKEN 24 HOURS REFRESH TOKEN UNLIMITED ACCESS TOKEN 4 HOURS Admin Users Consumer Users Privileged Scopes Requires admin users to log in every day Best UX, log in once and appear to be logged in forever Prevent applications from using privileged scopes without the user being present

Slide 77

Slide 77 text

RESOURCES

Slide 78

Slide 78 text

oauth.com

Slide 79

Slide 79 text

oauth.com/playground

Slide 80

Slide 80 text

oauth.net

Slide 81

Slide 81 text

developer.okta.com/signup

Slide 82

Slide 82 text

oauth2simplified.com

Slide 83

Slide 83 text

Thank You! @aaronpk developer.okta.com