Upgrade to Pro — share decks privately, control downloads, hide ads and more …

OAuth 101 - Internet Identity Workshop XXXI

OAuth 101 - Internet Identity Workshop XXXI

Aaron Parecki

October 20, 2020
Tweet

More Decks by Aaron Parecki

Other Decks in Technology

Transcript

  1. RFC6749 RFC6750 CLIENT TYPE AUTH METHOD GRANT TYPE RFC6819 RFC7009

    RFC7592 RFC7662 RFC7636 RFC7591 RFC7519 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
  2. The Password Anti-Pattern • How do you revoke this app’s

    access? • Do you trust the app to not store your password? • Do you trust the app to access only the things it says it needs? • Do you trust the app to not do things like change your password or delete your account?
  3. Authorization Code OAuth Flows Device Flow Client Credentials Implicit Password

    web mobile SPA browserless devices server-to-server CLI CLI >_ >_
  4. ROLES IN OAUTH OAuth Server (Authorization Server) aka the token

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

    factory API (Resource Server) The Application (Client) The User (Resource Owner) Device (User Agent) Travis-CI.org GitHub
  6. ROLES IN OAUTH OAuth Server (Authorization Server) aka the token

    factory API (Resource Server) The Application (Client) The User (Resource Owner) Device (User Agent) iPhone App Okta Your API
  7. Public Confidential Application running on a server Has the ability

    to keep strings secret since code is running in a trusted environment The application can't be deployed with a secret JavaScript/Single-Page apps: "view source" Native apps: decompile and extract strings Credentialed Obtains credentials on first launch A native app can use Dynamic Client Registration to obtain credentials which it can use in later exchanges
  8. 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 hash 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 ?
  9. 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
  10. Front Channel Benefits https://accounts.google.com/?... ‣ The user being involved enables

    them to give consent ‣ Enables easier two-factor authorization integration ‣ Doesn't require the receiver to have a publicly routable IP (e.g. can work on a phone)
  11. Generate the Code Verifier 4A6hBupTkAtgbaQs39RSELUEqtSWTDTcRzVh1PpxD5YVKllU Generate a random string 43-128

    characters long ipSBt30y48l401NGbLjo026cqwsRQzR5KI40AuLAdZ8 The challenge is the SHA256 hash of the verifier string base64url(sha256(code_verifier)) Generate the Code Challenge
  12. The app builds the auth link https://authorization-server.com/auth? response_type=code& client_id=CLIENT_ID& redirect_uri=REDIRECT_URI&

    scope=photos& state=1234zyx& code_challenge=XXXXXXXXXXXXX& code_challenge_method=S256 Include the code challenge (the hashed value) in the request
  13. The user is redirected back to the application with an

    authorization code example://callback?error=access_denied&state=1234xyz The user is redirected back to the application with an error code If User Denies If User Allows example://callback? code=AUTH_CODE_HERE& state=1234zyx
  14. Exchange the Code for an Access Token Verify state, then

    make a POST request: • 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 • code_verifier=VERIFIER_STRING - The plaintext code verifier initially created
  15. Exchange the Code for an Access Token POST https://api.authorization-server.com/token grant_type=authorization_code&

    code=AUTH_CODE_HERE& redirect_uri=REDIRECT_URI& client_id=CLIENT_ID& code_verifier=VERIFIER_STRING
  16. Exchange the Code for an Access Token { "access_token":"RsT5OjbzRn430zqMLgV3Ia", "expires_in":3600,

    "refresh_token":"64d049f8b2119a12522d5dd96d5641af5e8" } The server compares the code_verifier with the code_challenge that was in the request when it generated the authorization code, and responds with an access token.
  17. PKCE Ensures the app that receives the authorization code is

    the same one that started the exchange
  18. Exchange the Refresh Token for an Access Token POST https://authorization-server.com/token

    grant_type=refresh_token& refresh_token=REFRESH_TOKEN& client_id=CLIENT_ID& client_secret=CLIENT_SECRET
  19. New Access Token in the Response { "access_token": "RsT5OjbzRn430zqMLgV3Ia", "expires_in":

    3600, "refresh_token": "64d049f8b21191e12522d5d96d5641af5e8" }
  20. SIGN IN user authenticates access token & refresh token authorization

    request store refresh token in secure storage
  21. SIGN IN biometrics unlock refresh token new access token &

    refresh token already has refresh token use refresh token to get new access token
  22. 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
  23. 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": "[email protected]" } header claims
  24. are you an app? are you an API? Authorization: Bearer

    RsT5OjbzRn430zqMLgV3Ia just use the token parse/extract/introspect the token { "sub": "{USER_ID}", "aud": "{CLIENT_ID}", "exp": 1524240821, "scp": "create" }
  25. Access Token Validation The Fast Way The Strong Way Local

    Validation Remote Introspection 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}
  26. 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
  27. API Gateway Token Validation API Gateway CUSTOMER API BILLING API

    ORDER API LOCAL VALIDATION TOKEN INTROSPECTION attacker attacker valid token valid token expired expired revoked revoked malformed valid token valid token revoked revoked X X X X X valid token revoked valid token revoked X
  28. JWT Profile for Access Tokens Describes a standard set of

    JWT claims to use in a JWT access token. This enables resource servers to be built with standard libraries to validate tokens.
  29. JWT Authorization Request (JAR) Create a JWT describing the authorization

    request instead of building a URL Provides: integrity protection, request authentication, confidentiality
  30. OAuth 2.1 Consolidate the OAuth 2.0 specs,
 adding best practices,

    
 removing deprecated features Capture current best practices in OAuth 2.0 under a single name
  31. OAuth 2.0 RFC6749 OAuth Core Authorization Code Implicit Password Client

    Credentials RFC6750 Bearer Tokens Tokens in HTTP Header Tokens in POST Form Body Tokens in GET Query String RFC7636 +PKCE RFC8252 PKCE for mobile Browser App BCP PKCE for SPAs PKCE for confidential clients Security BCP
  32. Pushed Authorization Requests (PAR) • Currently, the authorization request is

    sent in the front-channel • Front-channel is susceptible to inspection and modification • PAR initiates the OAuth flow from the back-channel oauth.net/2/pushed-authorization-requests
  33. Pushed Authorization Requests (PAR) GET /authorize?response_type=code &client_id=s6BhdRkqt3&state=af0ifjsldkj &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb HTTP/1.1 Host:

    as.example.com POST /as/par HTTP/1.1 Host: as.example.com Content-Type: application/x-www-form-urlencoded Authorization: Basic czZCaGRSa3F0Mzo3RmpmcDBaQnIxS3REUmJuZlZkbUl3 response_type=code &client_id=s6BhdRkqt3&state=af0ifjsldkj &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb Instead of: Push the request to the AS: oauth.net/2/pushed-authorization-requests
  34. Pushed Authorization Requests (PAR) { "request_uri": "urn:example:bwc4JK-ESC0w8acc191e-Y1LTC2", "expires_in": 90 }

    GET /authorize?request_uri= urn%3Aexample%3Abwc4JK-ESC0w8acc191e-Y1LTC2 HTTP/1.1 AS responds with a URL: User visits that URL, authorization request details are hidden! oauth.net/2/pushed-authorization-requests
  35. Specs Built on OAuth • OpenID Connect (openid.net) • FAPI

    (Financial-Grade API) • UMA (User-Managed Access) • IndieAuth (indieauth.net)