$30 off During Our Annual Pro Sale. View Details »

Auth 101 - Longhorn PHP

Auth 101 - Longhorn PHP

Auth; almost every application employs it. From verifying that a user is who they say they are, to restricting access to a protected resource. If your application isn’t secure, there’s a lot to lose. Let’s learn the difference between authentication and authorisation, and the best ways to implement them.

Katy Ereira

November 09, 2022
Tweet

More Decks by Katy Ereira

Other Decks in Programming

Transcript

  1. @maccath | Katy Ereira | #LonghornPHP
    Auth 101.
    What even is Auth anyway?

    View Slide

  2. @maccath | Katy Ereira | #LonghornPHP
    What do we mean by ‘auth’?
    ● Authentication?
    ● Authorisation?
    ● What’s the difference?

    View Slide

  3. @maccath | Katy Ereira | #LonghornPHP
    Authentication vs Authorisation
    Authentication (authn) is used to determine that…
    ● Your identity can be verified
    ● Your credentials match what is held on file
    ● Your request is authentic

    View Slide

  4. @maccath | Katy Ereira | #LonghornPHP
    Authentication vs Authorisation
    Authorisation (authz) is used to determine that…
    ● You are admitted entry to a protected area
    ● You possess the correct key
    ● You are permitted access to a resource
    ● You have been authorised to perform an action

    View Slide

  5. @maccath | Katy Ereira | #LonghornPHP
    Remember:
    Authentication leads to authorisation, but authorisation never leads to
    authentication.

    View Slide

  6. @maccath | Katy Ereira | #LonghornPHP
    Authentication

    View Slide

  7. @maccath | Katy Ereira | #LonghornPHP
    Authentication Factors

    View Slide

  8. @maccath | Katy Ereira | #LonghornPHP
    Something You Know
    ● A username and password
    ● A PIN
    ● Answer to a secret question

    View Slide

  9. @maccath | Katy Ereira | #LonghornPHP
    Something You Have
    ● A key
    ● A certificate
    ● Access to a smart device
    ● An email address or phone number

    View Slide

  10. @maccath | Katy Ereira | #LonghornPHP
    Something You Are
    ● Biometrics: fingerprints, voice, retina
    ● Location-based
    ● Facial recognition

    View Slide

  11. @maccath | Katy Ereira | #LonghornPHP
    The Humble Password

    View Slide

  12. @maccath | Katy Ereira | #LonghornPHP
    Let’s talk about password security…
    ● Passwords must be strong
    ● Passwords must be hashed and salted before storing
    ● Passwords should not be the only authentication factor

    View Slide

  13. @maccath | Katy Ereira | #LonghornPHP
    Salting & hashing a password
    $password = $_POST['password']; // The plaintext password.
    $algorithm = PASSWORD_DEFAULT; // Choose an algorithm.
    $hash = password_hash($password, $algorithm); // Hash and salt it.
    // You may now store the value of $hash in your database!
    save-password.php

    View Slide

  14. @maccath | Katy Ereira | #LonghornPHP
    The Password Hash Function
    ● Creates a salt automatically so you don’t have to!
    ● Returns the salt in the hash so no separate storage required.
    ● Hash contains the algorithm parameters used to generate it.
    $2y$07$CCk9VkXcWxRIhy90tY21SeYjnHxoe0t/8.XQ3IV5KEelwrFTNu4Ge

    View Slide

  15. @maccath | Katy Ereira | #LonghornPHP
    Supported Algorithms
    ● password_hash() only supports strong hashing algorithms.
    ● PASSWORD_DEFAULT is the PHP default algorithm; this can change if
    something stronger comes along. Currently, it is PASSWORD_BCRYPT
    ● You can also use PASSWORD_ARGON2I and PASSWORD_ARGON2ID if
    PHP was compiled with Argon2 support.

    View Slide

  16. @maccath | Katy Ereira | #LonghornPHP
    Verifying a password
    $password = $_POST['password']; // The plaintext password
    /** @var object{hash: string} $user */
    $hash = $user->hash; // The stored password hash
    $valid = password_verify($password, $hash);
    verify-password.php

    View Slide

  17. @maccath | Katy Ereira | #LonghornPHP
    Bonus points - rehashing!
    // … cont’d
    if ($valid && password_needs_rehash($hash, PASSWORD_DEFAULT)) {
    // Create a new hash, and replace the old one
    $user->hash = password_hash($password, PASSWORD_DEFAULT);
    }
    verify-password.php

    View Slide

  18. @maccath | Katy Ereira | #LonghornPHP
    Application
    User
    credentials
    Auth Handler
    Action Error 401
    Password Verify

    View Slide

  19. @maccath | Katy Ereira | #LonghornPHP
    https://xkcd.com/538/

    View Slide

  20. @maccath | Katy Ereira | #LonghornPHP
    Multi-factor Authentication / 2FA
    Anyone can obtain and use a password; it doesn’t verify anything!
    Two or more different authentication factors goes much further in determining
    the authenticity of a user.

    View Slide

  21. @maccath | Katy Ereira | #LonghornPHP
    Application
    User
    Action
    Error 401
    Auth Handler
    credentials
    answer
    Password Verify
    Challenge
    Verify

    View Slide

  22. @maccath | Katy Ereira | #LonghornPHP
    Challenge Ideas
    ● TOTP - Time-based One Time Password
    ● Email confirmation link
    ● SMS OTP

    View Slide

  23. @maccath | Katy Ereira | #LonghornPHP
    Remember:
    Passwords verify nothing; use two or more factors to really authenticate
    your users!

    View Slide

  24. @maccath | Katy Ereira | #LonghornPHP
    Persisting State

    View Slide

  25. @maccath | Katy Ereira | #LonghornPHP
    Using Sessions
    A session is a way of persisting data between requests. Session data is stored
    server-side.
    When a session is created in PHP, a random session ID is generated. The ID is
    stored in a `PHPSESSID` cookie.

    View Slide

  26. @maccath | Katy Ereira | #LonghornPHP
    Application
    Auth Handler
    User
    Action
    Error 401
    Create Session
    Verify
    req. with credentials
    resp. with session ID
    Session Store

    View Slide

  27. @maccath | Katy Ereira | #LonghornPHP
    Creating a logged in session
    // ...cont’d
    $valid = password_verify($password, $hash);
    if ($valid) {
    session_start();
    $_SESSION['loggedIn'] = true;
    }
    login.php

    View Slide

  28. @maccath | Katy Ereira | #LonghornPHP
    Application
    Auth Handler
    User
    Action
    Error 401
    Update Session
    Check Session
    req. with session ID
    Session Store

    View Slide

  29. @maccath | Katy Ereira | #LonghornPHP
    Checking if a user is logged in
    session_start();
    if ($_SESSION['loggedIn'] === true) {
    // User is logged in!
    }
    login.php

    View Slide

  30. @maccath | Katy Ereira | #LonghornPHP
    Logging out
    session_start();
    unset($_SESSION['loggedIn']);
    // User is no longer logged in!
    logout.php

    View Slide

  31. @maccath | Katy Ereira | #LonghornPHP

    Using JWTs
    JSON Web Tokens are an open, industry standard RFC 7519 method
    for representing claims securely between two parties.
    Reference: https:/
    /jwt.io/

    View Slide

  32. @maccath | Katy Ereira | #LonghornPHP
    Using JWTs
    A JWT contains data, similar to the data a PHP Session might contain. The
    difference is that JWTs do not require server storage.
    Using a shared secret, JWTs can be decoded and validated across multiple
    services.

    View Slide

  33. @maccath | Katy Ereira | #LonghornPHP
    Application
    Auth Handler
    User
    Response Error 401
    req. with credentials
    Create JWT
    Verify
    resp. with JWT

    View Slide

  34. @maccath | Katy Ereira | #LonghornPHP
    Application
    Auth Handler
    User
    Action Error 401
    Validate JWT
    req. with JWT

    View Slide

  35. @maccath | Katy Ereira | #LonghornPHP
    Sample JWT
    eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODk
    wIiwibmFtZSI6IkthdHkiLCJpYXQiOjE1MTYyMzkwMjJ9.DQvkUBA1vHZSIJ
    46Ue1yXibd0rWoylJFztYrXC50h2A

    View Slide

  36. @maccath | Katy Ereira | #LonghornPHP
    Part 1 - Header
    eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
    {
    "alg": "HS256",
    "typ": "JWT"
    }

    View Slide

  37. @maccath | Katy Ereira | #LonghornPHP
    Part 2 - Payload (Claims)
    eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkthdHkiLCJpYXQiOjE1MTYyMzkwMjJ9
    {
    "sub": "1234567890",
    "name": "Katy",
    "iat": 1516239022
    }

    View Slide

  38. @maccath | Katy Ereira | #LonghornPHP
    Part 3 - Signature
    DQvkUBA1vHZSIJ46Ue1yXibd0rWoylJFztYrXC50h2A
    HMACSHA256(
    base64UrlEncode(header) + "." +
    base64UrlEncode(payload),
    my-super-secret
    )

    View Slide

  39. @maccath | Katy Ereira | #LonghornPHP
    Q?
    A. By comparing the signature to a hash using your shared secret, you can
    verify that the contents of the JWT are authentic and have not been
    tampered with.
    How can I trust that a JWT is authentic?

    View Slide

  40. @maccath | Katy Ereira | #LonghornPHP
    Registered Claims
    JWTs have a set of registered (useful, interoperable) claims, which include:
    ○ aud - audience
    ○ nbf - not before
    ○ iss - issuer
    ○ exp - expiry
    ○ iat - issued at
    ○ sub - subject

    View Slide

  41. @maccath | Katy Ereira | #LonghornPHP
    Custom Claims
    It is possible to add your own custom claims to a JWT. Custom claims should
    be namespaced to avoid collisions. It is recommended to namespace claims
    using a domain you control.
    {
    "sub": "Katy",
    "https://katy-ereira.co.uk/fav_color": "purple"
    }

    View Slide

  42. @maccath | Katy Ereira | #LonghornPHP
    Other Considerations
    ● Access tokens are sent in request headers; many servers do not support headers larger
    than 8kB. Try and keep your JWT and its claims as minimal as possible!
    ● JWTs cannot be invalidated, but they can expire. Set a short expiry time and validate
    against this to mitigate interception.
    ● Claims within JWTs are only base64 encoded. Don’t encode anything sensitive!

    View Slide

  43. @maccath | Katy Ereira | #LonghornPHP
    Remember:
    Sessions require state storage; JWTs are stateless and can be verified
    across multiple services using a shared secret.

    View Slide

  44. @maccath | Katy Ereira | #LonghornPHP
    Authorisation Strategies

    View Slide

  45. @maccath | Katy Ereira | #LonghornPHP
    Authorisation Strategies
    ● ABAC
    ● RBAC
    ● ReBAC

    View Slide

  46. @maccath | Katy Ereira | #LonghornPHP
    Authorisation Strategies
    ● ABAC - Attribute Based Access Control
    ● RBAC - Role Based Access Control
    ● ReBAC - Relationship Based Access Control

    View Slide

  47. @maccath | Katy Ereira | #LonghornPHP
    Attribute Based Access Control
    “My age is over 18 therefore I am permitted to play the lottery”
    ● Very granular and flexible.
    ● Can be used to create complex access conditions.
    ● Can consider of a large number of attributes
    ○ nature of actions, time, location, relationships, roles, ages, etc.

    View Slide

  48. @maccath | Katy Ereira | #LonghornPHP
    Role Based Access Control
    “I am a site administrator therefore I am authorised to delete posts”
    ● Applies set permissions to generalised groups of people
    ● Less complex access conditions when compared with ABAC
    ● May be harder to scale as the number of roles and permissions grow

    View Slide

  49. @maccath | Katy Ereira | #LonghornPHP
    Relationship Based Access Control
    “I teach this student, so I may view their reports”
    ● Easy to reason about
    ● No need to assign roles or attributes
    ● Harder to scale; when relationship structures evolve, so must the access control

    View Slide

  50. @maccath | Katy Ereira | #LonghornPHP
    OAuth 2.0

    View Slide

  51. @maccath | Katy Ereira | #LonghornPHP

    OAuth 2.0
    OAuth 2.0 is the industry-standard protocol for authorization.
    OAuth 2.0 focuses on client developer simplicity while providing
    specific authorization flows for web applications, desktop
    applications, mobile phones, and living room devices.
    Reference: https:/
    /oauth.net/2/

    View Slide

  52. @maccath | Katy Ereira | #LonghornPHP
    Resource Owner
    A Resource Owner is a user or system that owns a protected resource.
    A Resource Owner can Authorise access to the resources they own.

    View Slide

  53. @maccath | Katy Ereira | #LonghornPHP
    Client
    A Client is a system that requires access to resources owned by a
    Resource Owner and protected by a Resource Server.
    To access resources, a Client must be Authorised by the Resource Owner.

    View Slide

  54. @maccath | Katy Ereira | #LonghornPHP
    Auth Server
    The Auth Server receives requests from the Client for access to protected
    resources.
    It issues access credentials upon successful Authentication of, and
    Authorisation by the Resource Owner.

    View Slide

  55. @maccath | Katy Ereira | #LonghornPHP
    Resource Server
    The Resource Server protects the Resource Owner's resources.
    It receives resource access requests from the Client. The Client sends
    access credentials along with its request, which the Resource Server
    verifies.
    Upon verification, the Resource Server returns the requested resources.

    View Slide

  56. @maccath | Katy Ereira | #LonghornPHP
    Auth Server
    Client Resource Owner
    Authorise
    Authenticate
    Access Credentials
    Resource Server
    Verify Credentials
    Action 401
    (e.g. mobile app)
    (e.g. an API)
    (e.g. a user)
    (e.g. Google accounts)

    View Slide

  57. @maccath | Katy Ereira | #LonghornPHP
    OAuth 2.0 Providers

    View Slide

  58. @maccath | Katy Ereira | #LonghornPHP
    Providers?
    There are many existing providers of OAuth 2.0 implementations. These
    include: Facebook, Google, LinkedIn, Instagram, etc.
    By registering a Client, you can ask a Resource Owner for Authorisation using
    the provider’s OAuth Server. An authenticated user’s email address may be all
    your Resource Server needs to validate and fulfil the request.

    View Slide

  59. @maccath | Katy Ereira | #LonghornPHP
    Creating an OAuth 2.0 Provider?
    Of course, you can implement your own OAuth 2.0 provider by following the
    OAuth 2.0 specification.
    For now, let’s assume we are integrating with an existing OAuth 2.0 provider
    such as Google, and that our services have their own database of users with
    email addresses that belong to Google accounts.

    View Slide

  60. @maccath | Katy Ereira | #LonghornPHP
    Grants

    View Slide

  61. @maccath | Katy Ereira | #LonghornPHP
    Grants
    There are various ways for a resource owner to grant access to a protected
    resource via an OAuth provider.
    Each method for receiving authorisation to access to a protected resource is
    called a ‘Grant’.

    View Slide

  62. @maccath | Katy Ereira | #LonghornPHP
    Authorisation Code Grants
    A single-use authorisation code is exchanged for an access token. The authorisation
    code itself can be securely transferred around a server-side application.
    Proof Key for Code Exchange (PKCE) is an additional step that makes authorisation
    code grants more secure for mobile and single-page applications.

    View Slide

  63. @maccath | Katy Ereira | #LonghornPHP
    Auth Server
    Client Resource Owner
    Authorise
    Authenticate
    Generate Code
    Resource Server
    Validate JWT
    Action 401
    Verify Code
    Generate JWT

    View Slide

  64. @maccath | Katy Ereira | #LonghornPHP
    Auth Server
    Client Resource Owner
    Authorise
    Authenticate
    Generate Code
    Resource Server
    Validate JWT
    Action 401
    Verify Code
    Generate JWT

    View Slide

  65. @maccath | Katy Ereira | #LonghornPHP
    Resource Owner Credentials Grant
    For absolutely trusted clients only, the Resource Owner can give its own
    credentials to the Client (i.e. their username and password), which the Client
    can then use to authorise with the Auth Server.

    View Slide

  66. @maccath | Katy Ereira | #LonghornPHP
    Auth Server
    Client
    Resource Owner
    Verify Credentials
    Generate JWT
    Resource Server
    Validate JWT
    Action 401

    View Slide

  67. @maccath | Katy Ereira | #LonghornPHP
    Q?
    A. You can’t; which is why the OAuth working group recommends against
    using or enabling this grant in your OAuth server, and it has been
    intentionally omitted from the draft OAuth 2.1 spec.
    Ref: https:/
    /datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics-19#section-2.4
    How can I trust that the client will store
    the user’s credentials securely?

    View Slide

  68. @maccath | Katy Ereira | #LonghornPHP
    Client Credentials Grant
    A Client uses its own credentials (e.g. a client ID and secret) to authorise with
    the Auth Server.
    This type of grant is used for non-interactive services that do not involve a
    Resource Owner; e.g. machine-to-machine operations.

    View Slide

  69. @maccath | Katy Ereira | #LonghornPHP
    Auth Server
    Client
    Verify Credentials
    Generate JWT
    Resource Server
    Validate JWT
    Action 401

    View Slide

  70. @maccath | Katy Ereira | #LonghornPHP
    Device Authorisation Grant
    Can be used to authorise browserless devices, such as smart TVs.
    Does not require any interaction with the Auth Server; instead, depends on the
    Resource Owner authenticating and authorising the device manually.

    View Slide

  71. @maccath | Katy Ereira | #LonghornPHP
    Client Auth Server
    Resource Owner Verify Credentials
    Resource Server
    Validate JWT
    Action 401
    Issue
    Code
    Verify Code
    Request Access
    Issue
    JWT
    Grant Access
    Granted?
    display code
    manual auth

    View Slide

  72. @maccath | Katy Ereira | #LonghornPHP
    Refresh Token Grant
    A previously authorised Client can refresh its own grant using a securely
    stored, longer lived refresh token.
    A Client can maintain access to protected resources without having to ask the
    Resource Owner for re-authorisation.

    View Slide

  73. @maccath | Katy Ereira | #LonghornPHP
    Auth Server
    Client
    Verify Refresh
    Token
    Generate JWT
    Resource Server
    Validate JWT
    Action 401
    Resource Owner
    prior auth

    View Slide

  74. @maccath | Katy Ereira | #LonghornPHP
    Remember:
    You can use multiple grant types depending on the interaction required
    between your services.

    View Slide

  75. @maccath | Katy Ereira | #LonghornPHP
    Other Security Considerations

    View Slide

  76. @maccath | Katy Ereira | #LonghornPHP
    Other Considerations
    ● Use HTTPS - always!
    ● Validate redirect URLs,
    ● Short-lived access tokens, long lived refresh tokens
    ● Invalidate longer lived tokens.
    ● Don’t expose private information.

    View Slide

  77. @maccath | Katy Ereira | #LonghornPHP
    It’s all too complicated!

    View Slide

  78. @maccath | Katy Ereira | #LonghornPHP
    There’s
    saas for
    that

    View Slide

  79. @maccath | Katy Ereira | #LonghornPHP
    Time for a recap...
    ● Authentication vs Authorisation
    ● Authentication Factors
    ● Password Security
    ● Authorisation strategies
    ● Sessions vs. JWTs
    ● OAuth 2.0 Spec

    View Slide

  80. @maccath | Katy Ereira | #LonghornPHP
    … later, in Auth 102?
    ● OpenID
    ● Identity Access Management (IAM)
    ● Threat detection
    ● Integrating with Auth0
    ● … what else did I miss?

    View Slide

  81. @maccath | Katy Ereira | #LonghornPHP
    Further Reading & Helpful Resources
    ● Decode and validate JWTs: https:/
    /jwt.io
    ● OAuth simplified: https:/
    /oauth.com
    ● Auth0 - auth SaaS: https:/
    /auth0.com
    ● OWASP Auth:
    https:/
    /cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html

    View Slide

  82. @maccath | Katy Ereira | #LonghornPHP
    https://joind.in/talk/eb34d

    View Slide