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

Building Clients for OpenID Connect/OAuth 2-based Systems

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. Building Clients for OpenID
    Connect/OAuth 2-based Systems
    Dominick Baier
    @leastprivilege

    View Slide

  2. 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

    View Slide

  3. 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

    View Slide

  4. 4
    @leastprivilege / @brocklallen
    It's complicated!
    https://openid.net/wg/
    https://tools.ietf.org/wg/oauth/

    View Slide

  5. 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

    View Slide

  6. 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

    View Slide

  7. 7
    @leastprivilege / @brocklallen
    Challenges for Clients
    • Request token
    • Use token

    View Slide

  8. 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

    View Slide

  9. 9
    @leastprivilege / @brocklallen
    Use Token
    • Token (typically) transmitted via Authorization header
    – form body or query string as alternative
    Authorization: Bearer
    GET /service/resource
    https://tools.ietf.org/html/rfc6750

    View Slide

  10. 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

    View Slide

  11. 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

    View Slide

  12. 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

    View Slide

  13. 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

    View Slide

  14. 14
    @leastprivilege / @brocklallen
    Front-Channel: Authorization Code Flow Response
    GET /cb?code=xyz

    View Slide

  15. 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"
    }

    View Slide

  16. 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)

    View Slide

  17. 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

    View Slide

  18. 18
    @leastprivilege / @brocklallen
    Hybrid Flow Response

    name="id_token"
    value="xjsj…aas" />
    name="code"
    value="i8j1…jj19" />

    POST /cb
    cryptographically
    linked via c_hash

    View Slide

  19. 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/

    View Slide

  20. 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

    View Slide

  21. 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

    View Slide

  22. 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

    View Slide

  23. 23
    @leastprivilege / @brocklallen
    Anti Pattern: Resource Owner Password Flow
    Username
    Password
    Login
    username/password
    token
    token
    trust
    Token service
    API

    View Slide

  24. 24
    @leastprivilege / @brocklallen
    Using a browser for driving the
    authentication workflow
    authentication request
    render UI & workflow

    View Slide

  25. 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)

    View Slide

  26. 26
    @leastprivilege / @brocklallen
    Receiving the response
    GET com.mycompany.nativeapp://cb?code=818…1299
    callback

    View Slide

  27. 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"
    }

    View Slide

  28. 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

    View Slide

  29. 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

    View Slide

  30. 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

    View Slide

  31. 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

    View Slide

  32. 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

    View Slide

  33. 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

    View Slide

  34. 34
    @leastprivilege / @brocklallen
    "SPA" Architecture
    HTML, JS, CSS APIs
    access
    token

    View Slide

  35. 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

    View Slide

  36. 36
    @leastprivilege / @brocklallen
    Response
    GET /callback.html
    #id_token=x12f…zsz
    &token=32x…133
    &expires_in=3600
    &token_type=Bearer

    View Slide

  37. 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

    View Slide

  38. 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

    View Slide

  39. 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();
    }
    });

    View Slide

  40. 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

    View Slide

  41. 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/

    View Slide

  42. 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

    View Slide

  43. 43
    @leastprivilege / @brocklallen
    Thanks!
    …and (because I always forget) - we have stickers!

    View Slide