Auth

Updated: 2021-02-21
  • Authentication (AuthN): determines identities, are you who you say you are (401 Unauthorized, but actually "unauthenticated" instead of "unauthorized")
  • Authorization (AuthZ): determines permissions, if your identity is confirmed, do you have access to the resource. (403 Forbidden)
  • front channel: less secure channel, e.g. from browser to server
  • back channel: highly secure channel, e.g. from server to server

Sessions vs Tokens

  • stateful: sessions using a cookie
  • stateless: tokens using JWT/OAuth, etc

Sessions

  • user submit username/password
  • server checks DB for verification
  • server creates a session (sessions are stored server-side, i.e. stateful) and issues a cookie with a session ID
  • user submit requests with the cookie
  • server validates it against session store and grant access
  • user logout or timeout, server destroy the session

Tokens

Not store on server-side, but stored in client storage; server does not need to keep track of user sessions

  • user submit username/password
  • server checks DB for verification
  • server generates a temporary token and sends back
  • user stores token in client storage
  • user sends token along with each request
  • server verifies the token and grant access

Client Storage

  • localStorage: browser key-value store with JS API; has no expiration time; every site has its own, other sites cannot read/write; max size higher than cookie (5MB/domain vs 4KB/cookie); good for public, non-sensitive, string data
  • sessionStorage: gets cleared when page is closed

HTTP Authentication

HTTP supports the use of several authentication mechanisms to control access to pages and other resources. These mechanisms are all based around the use of the 401 status code and the WWW-Authenticate response header.

When you send a request without credentials:

GET /home HTTP/1.1
Host: ...

You will get a 401 Unauthorized response(though it is actually Unauthenticated instead of Unauthorized):

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic realm="..."

Now send the request WITH the credentials:

GET /home HTTP/1.1
Host: ...
Authorization: Basic Zm9vOmJhcg==

You should get 200 OK

Where the word "Basic" is just one of the authentication mechanisms.

Defined in RFC 1954.

Basic

  • simplest technique for enforcing access controls
  • doesn't require cookies, session identifiers, or login pages
  • uses standard fields in the HTTP header, obviating the need for handshakes
  • <username>:<password> string encoded with Base64 in transit, but not encrypted or hashed in any way, should only be used with HTTPS
  • has to be sent in the header of each HTTP request(the web browser needs to cache credentials)
  • no "log out"

Digest

The client sends a hashed form of the password to the server. Although, the password cannot be captured over HTTP, it may be possible to replay requests using the hashed password.

NTLM

This uses a secure challenge/response mechanism that prevents password capture or replay attacks over HTTP. However, the authentication is per connection and will only work with HTTP/1.1 persistent connections. For this reason, it may not work through all HTTP proxies and can introduce large numbers of network round trips if connections are regularly closed by the web server.

Form-based Authentication

  • not formalized by any RFC; not using the formal HTTP authentication techniques (basic or digest).
  • use the standard HTML form fields to pass the username and password values to the server.
  • the server validates the credentials, creates a session which will be passed between client and server in following communications.
  • supports "log off", or the server logs the user off (e.g. due to inactivity) by invalidating the session key. This is the key difference comparing to basic auth.
  • similar to basic auth, has to use with HTTPS

OAuth 2.0

3 roles:

  • Client
  • Resource Server
  • Auth Server

2 kinds of tokens:

  • Access Token: short-lived(~1hr), grants client access to the Resource Server.
  • Refresh Token: long-lived(duration of log-in), grants client the ability to get Access Token from Auth Server.

Example Flow:

  • Client redirects to Auth Server for user login with redirect URI (for callback) and scope
  • After login and consent, Auth Server redirects to Client with Authorization Code back to Client (in front channel)
  • Client use Authorization Code to get access token (via back channel, server to server)
  • Client uses access token to talk to resource server

Flows:

  • Authorization code

    • front + back channel
    • for web app with server backend
    • auth server returns authorization code in front channel, then client uses authorization code to get access code in back channel)
  • Authorization code with PKCE

    • for native mobile app
    • uses random code instead of client secret
  • Implicit

    • front channel only
    • for SPA with API backend, like pure React/Angular app
    • auth server returns access token directly, instead of authorization code)
  • Client credentials

    • back channel only
    • for microservices and APIs
  • Resource owner password credentials

    • back channel only
    • not recommended for new apps

OAuth 3.0 is under development: oauth.xyz

OpenID Connect

OAuth is authorization only, NOT for authentication. Use OpenID Connect for authentication:

  • set scope=openid in request
  • will return an ID token, which is a JWT

JWT: JSON Web Token

Format: concatenate header, payload, and signature using comma(,)

<header>.<payload>.<signature>
  • header: how the signature should be computed
  • payload: the data being communicated
  • signature: proves the source of data is authentic, signing <header>.<payload> using a secret key.

Encoded vs Signed vs Encrypted:

  • encoded: the 3 parts are url encoded so they can be used as part of url, however they are not encrypted
  • signed tokens: can verify the integrity of the claims in the payload, however the claims can still be visible if without encryption
  • encrypted: encrypted tokens hide the claims from other parties

Secret vs Public/Private keys:

  • JWT can be signed using a secret, e.g. HMAC algorithm
  • or by public/private key pair, e.g. RSA or ECDSA, in this case the signature certifies that the JWT is signed by the party holding the private key

json web token: https://jwt.io/

JWK vs JWS vs JWT vs JWE

  • RFC 7515 - JSON Web Signature (JWS)
  • RFC 7516 - JSON Web Encryption (JWE)
  • RFC 7517 - JSON Web Key (JWK)
  • RFC 7518 - JSON Web Algorithms (JWA)
  • RFC 7519 - JSON Web Token (JWT)

JWT by default is not encrypted; JWE specifies how encryption should be done.

IAM: Identity and Access Management

Once the source of the data is verified (e.g. by JWT's signature), we can check IAM to see if the user (some user info like id may be inside JWT's payload) has the permission to the requested resources.

3 types of entities:

  • Resources
  • Permissions
  • Roles

Identity-as-a-Service (IDaaS)

There are multiple identity related services even from the same cloud provider, and it can be confusing. One key difference is the target audience, take Google Cloud for example:

  • Cloud IAM: to control Google Cloud resources, e.g. who can create a new VM
  • Identity Platform/Firebase Auth: for end users, or GCP customers' customers
  • BeyondCorp, Context-Aware Access: for IT admins to control employees access

Okta

The most popular IDaaS, a public company.

Auth0

https://auth0.com/

auth0 architecture: http://highscalability.com/blog/2018/8/27/auth0-architecture-running-in-multiple-cloud-providers-and-r.html

Google Identity Platform and Firebase Auth

https://cloud.google.com/identity-platform/docs/product-comparison

https://firebase.google.com/docs/auth/

Cloud API: API Key Or Not

API Key can be stolen in many ways(e.g. accidentally checked-in GitHub). Use API Key if you do not have a backend and talk to third-party services directly; otherwise use your backend to handle auth to cloud APIs.

Kerberos

kinit: talk to KDCkey distribution center=> kerberos use Authentication Server(AS) and Ticket Granting Server(TGS)

Ticket Granting Ticket (TGT)

Universal (Centralized) vs Embedded Login

Universal Login is preferred.

  • Universal: login page is hosted on a different site, e.g. all Google login will be redirected to accounts.google.com, after successfully login user will be redirected back.
  • Embedded: the login form is embedded, the credentials will be sent to the backend or a different site for auth, in the latter case it will be cross-origin.

Single Sign-on

SAML/OIDC