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

Building Clients for OpenID Connect/OAuth 2-bas...

Building Clients for OpenID Connect/OAuth 2-based Systems

Dominick Baier

January 25, 2019
Tweet

More Decks by Dominick Baier

Other Decks in Programming

Transcript

  1. 2 @leastprivilege / @brocklallen Me • Independent Consultant – Specializing

    on Application Security Architectures – Working with Software Development Teams (ISVs and in-house) • Co-Creator of IdentityServer & IdentityModel OSS Project – Certified OpenID Connect & OAuth 2.0 Implementation for .NET – https://identityserver.io • Co-Creator of PolicyServer – Modern Authorization Solution – https://policyserver.io email [email protected] blog https://leastprivilege.com twitter @leastprivilege slides https://speakerdeck.com/leastprivilege
  2. 3 @leastprivilege / @brocklallen Objectives • Discuss common challenges for

    building clients • Look at recommended approaches for several client types – server to server – web applications – native/mobile applications – SPAs • Give you references to further reading material
  3. 5 @leastprivilege / @brocklallen Timeline 2005 SAML 2.0 2007 2009

    2012 2014 2015 2017 Soon Future OpenID Connect Session Management OpenID Connect Front-Channel Notifications OpenID Connect Back-Channel Notifications Authentication Method Reference Values OAuth 2.0 for Native Apps OAuth 2.0 Token Binding OpenID Connect Token Binding OpenID Connect Federation … OAuth 2.0 Token Exchange OAuth 2.0 Mutual TLS OAuth 2.0 Device Flow OAuth 2.0 Discovery OAuth 1.0 WS-Federation 1.2 OAuth 1.0a OAuth 2.0 Bearer Tokens OpenID Connect Core OpenID Connect Discovery OpenID Connect Dynamic Registration OAuth 2.0 Assertion Framework OAuth 2.0 Dynamic Client Registration OAuth 2.0 Token Introspection JSON Web Token (JWT) OAuth 2.0 JSON Web Token (JWT) Profile OAuth 2.0 SAML 2.0 Profile OAuth 2.0 PKCE
  4. 6 @leastprivilege / @brocklallen The Big Picture Browser Native App

    Server App "Thing" Web App Web API Web API Web API Security Token Service 1 2 1 public client 2 confidential client 1 2 2
  5. 8 @leastprivilege / @brocklallen Client Credentials Flow APIs Authorization Server

    Scopes: api1, api2 api3… client_id=client1, client_secret=***, scope=api1 api2 access token access token
  6. 9 @leastprivilege / @brocklallen Use Token • Token (typically) transmitted

    via Authorization header – form body or query string as alternative Authorization: Bearer <token> GET /service/resource https://tools.ietf.org/html/rfc6750
  7. 10 @leastprivilege / @brocklallen Token Management • Store tokens server-side

    – in-memory, distributed cache, cookie, session storage, database… • Pro-active – keep track of expiration and renew token ahead of time • Re-active – wait for 401, renew, re-send
  8. 11 @leastprivilege / @brocklallen Challenges for Clients • Request token

    – which protocol flow to use? – is a user involved? • Manage token – where to store them? – how to renew the token? – is long-lived access required? • Use token
  9. 12 @leastprivilege / @brocklallen User-Centric Clients • More front-end concerns

    – authenticate user • UI workflows – start/join (single sign-on) session • listening to session change notifications • potentially coordinating token storage with session lifetime – make API calls on behalf of the user – silently renew tokens • To accommodate all of these requirements, Authorization Code Flow was created
  10. 13 @leastprivilege / @brocklallen Front-Channel: Authorization Code Flow Request GET

    /authorize ?client_id=app1 &redirect_uri=https://app.com/cb &response_type=code &scope=openid email api1 api2 offline_access
  11. 15 @leastprivilege / @brocklallen Back-Channel: Retrieving Tokens • Exchange code

    for access & refresh token – using client id and secret code (client_id:client_secret) { id_token: "xxae…988", access_token: "xyz…123", refresh_token: "jdj9…192j", expires_in: 3600, token_type: "Bearer" }
  12. 16 @leastprivilege / @brocklallen Issues with Code Flow • Historically

    only designed for confidential clients • Code substitution attack – client can be tricked into using its client secret with a leaked/stolen code • Different mitigation approaches – OpenID Connect: Hybrid Flow – OAuth2: Proof Key for Code Exchange (PKCE)
  13. 17 @leastprivilege / @brocklallen Hybrid Flow Request GET /authorize ?client_id=app1

    &redirect_uri=https://app.com/cb &response_type=code id_token &response_mode=form_post &nonce=j1y…a23 &scope=openid email api1 api2
  14. 18 @leastprivilege / @brocklallen Hybrid Flow Response <form> <input type="hidden"

    name="id_token" value="xjsj…aas" /> <input type="hidden" name="code" value="i8j1…jj19" /> </form> POST /cb cryptographically linked via c_hash
  15. 19 @leastprivilege / @brocklallen Server-side Web Applications (e.g. ASP.NET Core)

    • Built-in features make writing clients easy – OpenID Connect authentication handler supports Hybrid Flow • extensibility points to customize behavior – token storage mechanism that is automatically tied to session • uses cookies for storage by default • can be replaced with distributed cache • can be used for automatic token lifetime management • Can revoke refresh tokens at logout time (if not needed anymore) https://leastprivilege.com/2019/01/14/automatic-oauth-2-0-token-management-in-asp-net-core/
  16. 20 @leastprivilege / @brocklallen Issues with Hybrid Flow • Heavier

    client libraries – id_token validation – cryptographic linking of artifacts • Identity token via front channel – might leak identity information – at least sub
  17. 21 @leastprivilege / @brocklallen Public Clients • So far we

    only looked at server-based clients – typically unique client IDs – can store a secret securely • Public clients cannot store a client secret securely – e.g. SPAs, mobile apps – 1:many mapping of client id to instance • Dynamic client registration can turn public into confidential client – additional bootstrapping infrastructure necessary
  18. 22 @leastprivilege / @brocklallen Native/Mobile Applications • Applications that have

    access to native platform APIs – desktop or mobile • "OAuth 2.0 for native Applications" – https://tools.ietf.org/html/rfc8252
  19. 23 @leastprivilege / @brocklallen Anti Pattern: Resource Owner Password Flow

    Username Password Login username/password token token trust Token service API
  20. 24 @leastprivilege / @brocklallen Using a browser for driving the

    authentication workflow authentication request render UI & workflow
  21. 25 @leastprivilege / @brocklallen Code Flow + PKCE GET /authorize

    ?client_id=nativeapp &scope=openid profile api1 api2 offline_access &redirect_uri=com.mycompany.nativeapp://cb &response_type=code &nonce=j1y…a23 &code_challenge=x929..1921 nonce = random_number code_verifier = random_number code_challenge = hash(code_verifier)
  22. 27 @leastprivilege / @brocklallen Requesting the access token • Exchange

    code for access token – using client id and code verifier code & code verifier (client_id) { id_token: "ka9…2129", access_token: "xyz…123", refresh_token: "dxy…103" expires_in: 3600, token_type: "Bearer" }
  23. 28 @leastprivilege / @brocklallen Proof-Key for Code Exchange (PKCE) •

    PKCE (RFC 7636) introduces a per-request client secret – allows binding front–channel to back-channel client – prohibits token substitution – also works without a client secret • Similar goals as nonce and c_hash approach – independent of OpenID Connect – verification happens on the token server
  24. 29 @leastprivilege / @brocklallen Token Management • Tokens should be

    stored using secure data storage provided by OS – e.g. KeyChain on iOS, DPAPI on Windows… – some support additional security mechanisms (e.g. biometrics) • Refresh can be automated by client libraries – e.g. using HTTP message handler & HttpClient • Tokens can be revoked when not needed anymore – logout – uninstall
  25. 30 @leastprivilege / @brocklallen Client Libraries • Native libraries –

    https://github.com/openid/AppAuth-iOS – https://github.com/openid/AppAuth-Android • C# .NET standard library (desktop .NET, UWP, mobile, iOS, Android) – https://github.com/IdentityModel/IdentityModel.OidcClient2 – https://github.com/IdentityModel/IdentityModel.OidcClient.Samples
  26. 31 @leastprivilege / @brocklallen Browser-based Clients (aka SPAs) • The

    most problematic client type from a security point of view – but also most popular client type • Unique attacks due to "shared execution environment" nature of browser – Cross-Site Request Forgery (CSRF) – Cross-Site Scripting (XSS) • Ongoing work in IETF to produce useful guidance – https://tools.ietf.org/html/draft-parecki-oauth-browser-based-apps
  27. 32 @leastprivilege / @brocklallen History (1) • Same-domain architectures –

    client and APIs are in same application or origin – cookies are used to secure AJAX calls • Problems and limitations – Cross-Site Request forgery • mitigation techniques well understood, but require extra work – cross-domain API access – non-browser API clients
  28. 33 @leastprivilege / @brocklallen History (2) • OAuth 2 implicit

    flow tried to solve those problems • Needed to work under certain constraints – no AJAX (CORS did not really exist yet) – no client secret
  29. 35 @leastprivilege / @brocklallen Implicit Flow Request GET /authorize ?client_id=app1

    &redirect_uri=https://app.com/cb.html &response_type=id_token token &nonce=j1y…a23 &scope=openid email api1 api2
  30. 37 @leastprivilege / @brocklallen Problems with Implicit Flow • Implicit

    flow is out-dated – relies solely on # vs ? handling in browser for leakage protection – tokens end up in URL history in browser – traditionally no protection against token substitution attacks • OpenID Connect added at_hash claim • needs client side crypto similar to Hybrid Flow • IETF wants to deprecate Implicit Flow – CORS widely deployed now – use Code Flow + PKCE instead
  31. 38 @leastprivilege / @brocklallen Token Management for JS Apps •

    Regardless of the flow, tokens will be stored in the browser – e.g. session storage – prone to XSS-based attacks • potential exfiltration of tokens • even worse with refresh tokens – Content Security Policy (CSP) highly recommended – but not always easy* – HTTP token binding might help in the future** • Token renewal should be tied to session lifetime – "Silent renew" technique – bind refresh tokens to session * https://www.youtube.com/watch?v=uf12a-0AluI ** https://groups.google.com/a/chromium.org/forum/#!topic/net-dev/8QD01FloF1o
  32. 39 @leastprivilege / @brocklallen Java Script Client Library • https://github.com/IdentityModel/oidc-client-js

    var settings = { authority: 'http://localhost:5152/', client_id: 'spa', redirect_uri: 'http://localhost:5152/callback.html', response_type: 'code', scope: 'openid profile api', }; var mgr = new Oidc.UserManager(settings); mgr.getUser().then(function (user) { if (user) { log("logged in", user); } else { mgr.signinRedirect(); } });
  33. 40 @leastprivilege / @brocklallen The new kid on the block:

    SameSite Cookies • Can prevent all cross-origin usages of cookies • On by default for ASP.NET Core authentication cookies – LAX only https://caniuse.com/#search=samesite
  34. 41 @leastprivilege / @brocklallen "BFF" Architecture Front-End private Back-End httponly

    + same site cookies APIs access token client https://leastprivilege.com/2019/01/18/an-alternative-way-to-secure-spas-with-asp-net-core-openid-connect-oauth-2-0-and-proxykit/
  35. 42 @leastprivilege / @brocklallen Further Reading • OAuth 2.0 –

    https://tools.ietf.org/html/rfc6749 • OAuth 2.0 Threat Model – https://tools.ietf.org/html/rfc6819 • OpenID Connect – https://openid.net/specs/openid-connect-core-1_0.html • PKCE – https://tools.ietf.org/html/rfc7636 • OAuth 2.0 Security Best Practices – https://tools.ietf.org/html/draft-ietf-oauth-security-topics-11 • SameSite Cookies – https://tools.ietf.org/html/draft-west-first-party-cookies-07 • ASP.NET Core Security & SPA Samples – https://github.com/leastprivilege/AspNetCoreSecuritySamples • Native Client Samples – https://github.com/IdentityModel/IdentityModel.OidcClient.Samples