The State of OAuth2


Published on

Slides from my talk at State of the Auth in Portland

Published in: Technology

The State of OAuth2

  1. 1. The State ofOAuth 2Aaron Parecki • @aaronpk • aaronparecki.comState of the Auth • January 2013
  2. 2. Before OAuth Apps stored the user’s password Apps got complete access to a user’s account Users couldn’t revoke access to an app except by changing their password Compromised apps exposed the user’s @aaronpk
  3. 3. Before OAuth Services recognized the problems with password authentication Many services implemented things similar to OAuth 1.0 Each implementation was slightly different, certainly not compatible with each @aaronpk
  4. 4. Before OAuth 1.0 Flickr: “FlickrAuth” frobs and tokens Google: “AuthSub” Facebook: requests signed with MD5 hashes Yahoo: BBAuth (“Browser-Based Auth”) @aaronpk
  5. 5. Some Current Implementers
  6. 6. The OAuth 2 Spec
  7. 7. Definitions Resource Owner: The User Resource Server: The API Authorization Server: Often the same as the API server Client: The Third-Party @aaronpk
  8. 8. Use Cases Web-server apps Browser-based apps Username/password access Application access Mobile @aaronpk
  9. 9. Use Cases – Grant Types Web-server apps – authorization_code Browser-based apps – implicit Username/password access – password Application access – client_credentials Mobile apps – @aaronpk
  10. 10. Web Server Apps Authorization Code @aaronpk
  11. 11. Create a “Log In” linkLink to: @aaronpk
  12. 12. Create a “Log In” linkLink to: @aaronpk
  13. 13. Create a “Log In” linkLink to: @aaronpk
  14. 14. Create a “Log In” linkLink to: @aaronpk
  15. 15. Create a “Log In” linkLink to: @aaronpk
  16. 16. User visits the authorization page @aaronpk
  17. 17. On success, user is redirected backto your site with auth code error, user is redirected back toyour site with error code @aaronpk
  18. 18. Server exchanges auth codefor an access tokenYour server makes the following requestPOST Body:grant_type=authorization_code&code=CODE_FROM_QUERY_STRING&redirect_uri=REDIRECT_URI&client_id=YOUR_CLIENT_ID& @aaronpk
  19. 19. Server exchanges auth codefor an access tokenYour server gets a response like the following{ "access_token":"RsT5OjbzRn430zqMLgV3Ia", "token_type":"bearer", "expires_in":3600, "refresh_token":"e1qoXg7Ik2RRua48lXIV"}or if there was an error{ "error":"invalid_request"} @aaronpk
  20. 20. Browser-Based Apps Implicit @aaronpk
  21. 21. Create a “Log In” linkLink to: @aaronpk
  22. 22. User visits the authorization page @aaronpk
  23. 23. On success, user is redirected backto your site with the access token inthe fragment error, user is redirected back toyour site with error code @aaronpk
  24. 24. Browser-Based AppsUse the “Implicit” grant typeNo server-side code neededClient secret not usedBrowser makes API requests @aaronpk
  25. 25. Username/Password Password @aaronpk
  26. 26. Password GrantPassword grant is only appropriate for trustedclients, most likely first-party apps only.If you build your own website as a client of yourAPI, then this is a great way to handle @aaronpk
  27. 27. Password Grant Type Only appropriate for your service’s website or your service’s mobile
  28. 28. Password GrantPOST Body:grant_type=password&username=USERNAME&password=PASSWORD&client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRETResponse:{ "access_token":"RsT5OjbzRn430zqMLgV3Ia", "token_type":"bearer", "expires_in":3600, "refresh_token":"e1qoXg7Ik2RRua48lXIV"} @aaronpk
  29. 29. Password GrantUser exchanges username and password for a tokenNo server-side code neededClient secret only used from confidential clients (Don’t send client secret from a mobile app!)Useful for developing a first-party login @aaronpk
  30. 30. Application Access Client Credentials @aaronpk
  31. 31. Client Credentials GrantPOST Body:grant_type=client_credentials&client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRETResponse:{ "access_token":"RsT5OjbzRn430zqMLgV3Ia", "token_type":"bearer", "expires_in":3600, "refresh_token":"e1qoXg7Ik2RRua48lXIV"} @aaronpk
  32. 32. Grant Type Summary authorization_code: Web-server apps implicit: Mobile and browser-based apps password: Username/password access client_credentials: Application @aaronpk
  33. 33. Grant Types & Response Types authorization_code: response_type=code implicit: @aaronpk
  34. 34. Grant Type @aaronpk
  35. 35. Authorization Code User visits auth page response_type=code User is redirected to your site with auth code Your server exchanges auth code for access token POST /token code=xxxxxxx& @aaronpk
  36. 36. Implicit User visits auth page response_type=token User is redirected to your site with access token Token is only available to the browser since it’s in the @aaronpk
  37. 37. Password Your server exchanges username/password for access token POST /token username=xxxxxxx&password=yyyyyyy& @aaronpk
  38. 38. Client Credentials Your server exchanges client ID/secret for access token POST /token client_id=xxxxxxx&client_secret=yyyyyyy& @aaronpk
  39. 39. Mobile Apps Implicit @aaronpk
  40. 40. @aaronpk
  41. 41. @aaronpk
  42. 42. Redirect back to your app Facebook app redirects back to your app using a custom URI scheme. Access token is included in the redirect, just like browser-based apps. fb2865://authorize/ @aaronpk
  43. 43. @aaronpk
  44. 44. Mobile ApplicationsUse the “Implicit” grant typeNo server-side code neededClient secret not usedMobile app makes API requests @aaronpk
  45. 45. Mobile Applications External user agents are best Use the service’s primary app for authentication, like Facebook – provides a superior user experience Or open native Safari on iPhone, still better than using an embedded browser Auth code or implicit grant type In both cases, the client secret should never be used, since it is possible to decompile the app which would reveal the @aaronpk
  46. 46. Accessing Resources So you have an access token. Now what? @aaronpk
  47. 47. Use the access token to makerequestsNow you can make requests using the access token.GET Bearer RsT5OjbzRn430zqMLgV3IaAccess token can be in an HTTP header or a query stringparameter @aaronpk
  48. 48. Eventually the access tokenmay expireWhen you make a request with an expired token, you willget this response{ "error":"expired_token"}Now you need to get a new access token! @aaronpk
  49. 49. Get a new access token usinga refresh tokenYour server makes the following requestPOST server gets a similar response as the original call tooauth/token with new tokens.{ "access_token":"RsT5OjbzRn430zqMLgV3Ia", "expires_in":3600, "refresh_token":"e1qoXg7Ik2RRua48lXIV"} @aaronpk
  50. 50. Scope Limiting access to @aaronpk
  51. 51. Limiting Access to Third @aaronpk
  52. 52. Limiting Access to Third @aaronpk
  53. 53. Limiting Access to Third @aaronpk
  54. 54. OAuth 2 scope Created to limit access to the third party. The scope of the access request expressed as a list of space-delimited strings. In practice, many people use comma-separators instead. The spec does not define any values, it’s left up to the implementor. If the value contains multiple strings, their order does not matter, and each string adds an additional access range to the requested @aaronpk
  55. 55. OAuth 2 scope on Facebook client_id=YOUR_APP_ID&redirect_uri=YOUR_URL &scope=email, @aaronpk
  56. 56. OAuth 2 scope on @aaronpk
  57. 57. OAuth 2 scope on Github client_id=...&scope=user,public_repo user • Read/write access to profile info only. public_repo • Read/write access to public repos and organizations. repo • Read/write access to public and private repos and organizations. delete_repo • Delete access to adminable repositories. gist • write access to @aaronpk
  58. 58. OAuth 2 scope The challenge is displaying this to the user succinctly in a way they will actually understand If you over-complicate it for users, they will just click “ok” until the app works, and ignore any warnings Read vs write is a good start for basic @aaronpk
  59. 59. So what’s wrong? @aaronpk
  60. 60. What I just described is one possible implementation of an OAuth 2 @aaronpk
  61. 61. Indecision No required token type No agreement on the goals of an HMAC-enabled token type No requirement to implement token expiration No guidance on token string size, or any value for that matter No strict requirement for registration Loose client type @aaronpk
  62. 62. Indecision (continued) Lack of clear client security properties No required grant types No guidance on the suitability or applicability of grant types No useful support for native applications (but lots of lip service) No required client authentication method No limits on Source: @aaronpk
  63. 63. The result: the OAuth RFC is a framework, not a @aaronpk
  64. 64. @aaronpk
  65. 65. @aaronpk
  66. 66. OAuth 2 Servers Implementing an OAuth 2 @aaronpk
  67. 67. Implementing an OAuth 2 Server
  68. 68. Implementing an OAuth 2 Server Find a server library already written: A short list available here: Read the OAuth spec in its entirety Study other implementations like Google Make decisions based on the security requirements of your application. In many cases the spec says SHOULD and leaves the choice up to the implementer. Understand the security implications of the implementation choices you @aaronpk
  69. 69. Implementing an OAuth 2 Server Choose which grant types you want to support Authorization Code – for traditional web apps Implicit – for browser-based apps and mobile apps Password – for your own website or mobile apps Client Credentials – if applications can access resources on their own Choose whether to support Bearer tokens, MAC or both If using Bearer tokens, choose whether to use a DB lookup or use self-container tokens Define appropriate scopes for your @aaronpk
  70. 70. Access Tokens Bearer tokens vs MAC @aaronpk
  71. 71. Bearer Tokens GET /1/profile HTTP/1.1 Host: Authorization: Bearer B2mpLsHWhuVFw3YeLFW3f2 Bearer tokens are a cryptography-free way to access protected resources. Relies on the security present in the HTTPS connection, since the request itself is not signed. Application developers do not need to do any cryptography, they just pass the token string in the @aaronpk
  72. 72. Dangers of Using Bearer TokensRequests are not signed, so are vulnerable to reply attacks if someone intercepts the token.When storing tokens in cookies, must ensure the cookie is only sent via an https connection.If a token is leaked, there is a large potential for @aaronpk
  73. 73. Security Recommendationsfor Clients Using Bearer TokensSafeguard bearer tokensValidate SSL certificatesAlways use httpsDon’t store bearer tokens in plaintext cookiesIssue short-lived bearer tokensDon’t pass bearer tokens in page @aaronpk
  74. 74. MAC TokensGET /1/profile HTTP/1.1Host: api.example.comAuthorization: MAC id="jd93dh9dh39D", nonce="273156:di3hvdf8”, mac="W7bdMZbv9UWOTadASIQHagZyirA="MAC tokens provide a way to make authenticated requests withcryptographic verification of the request.Similar to the original OAuth 1.0 method of using signatures.Application developers must sign each request, preventing forgeryand replay even when requests are sent in the clear. @aaronpk
  75. 75. Bearer, MAC, or Both? Should you support Bearer tokens, MAC tokens or both? MAC tokens are technically safer and more secure Application developers will prefer working with Bearer tokens since it is @aaronpk
  76. 76. Scalability Concerns Token lookups from a database can become a bottleneck. Can be addressed by heavy use of caching to avoid DB lookups Can be addressed by a good master/slave database architecture An alternative is to use “self-encoded” tokens where all the needed information is contained within the token string itself, avoiding the need to do a database @aaronpk
  77. 77. Self-Encoded Tokens The token is a string which is encrypted or signed The string contains all necessary information to avoid doing a database lookup These tokens cannot be revoked, so must expire frequently (requires heavy use of the refresh_token grant type) Can be implemented with either Bearer or MAC @aaronpk
  78. 78. DB Token Lookups vs Self-Encoded Tokens Token table probably looks like Token User ID Expiration Date Scopes Instead, encode that into a JSON payload which *is* the token:  {“user_id”:1000,”exp”:1355429676,”scopes”:[“email ”,”payment”]} See JSON Web Signature for example of signing this @aaronpk
  79. 79. JSON Web Signature Data Base64 Encoded { "typ":"JWT", eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9 "alg":"HS256” } { "usr":"username", eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MT "exp":1300819380, kzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9p "scope":["profile"] c19yb290Ijp0cnVlfQ } Signature @aaronpk
  80. 80. JSON Web Signature Complete Token Example: eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.eyJpc3M iOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA 6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.dBjftJeZ 4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk Header, data, signature are base64 encoded and concatenated with a “period” between @aaronpk
  81. 81. @aaronpk
  82. 82. Website  Source code available on Github  Please feel free to contribute to the website Contribute new lists of libraries, or help update @aaronpk
  83. 83. @aaronpk
  84. 84. Thanks. Aaron Parecki @aaronpk