Authentication mechanism for your API

Przemek Lewandowski

@haxoza

About me

Overview

  • Introduction
  • Credentials vs API Keys
  • Tokens vs Cookies
  • Selected auth methods
  • Summary

Design of API

  • Authentication
  • Resources
  • Methods on resources
  • Authroization

Identify client of API

  • Internal application or developers
    • Data belongs to the same organisation
  • External application or developers
    • Sharing data on behalf of your users
    • User should decide what to share

Take into account

  • Methods and standards
  • System requirements
  • System architecture
  • Security issues

Credentials
vs
API Keys

Credentials

  • Username/email and password
  • Set by the user
  • Only one valid password for the user
  • Should be encrypted on the server
  • Should not be send over the network
  • Allows access to all user's resources

API Keys

  • Depends on auth method
    • identifier and secret token
    • just a token
    • or else
  • Set by the system
  • One or many valid api keys per user
  • Identify client
  • Not encrypted on the server
  • Can expire
  • Can be assigned to only some resources

Common use case

Tokens vs Cookies

Tokens vs Cookies

  • Cookies are usually session based
  • Tokens are stateless
  • Tokens are mobile ready
  • Some say that sessions are not efficient
  • Cookies and CORS don't play well

Tokens vs Cookies

Selected auth methods

  • Basic Auth
  • Token Auth
  • Digest Auth
  • JSON Web Token Auth
  • OAuth 2.0 / OpenID

Further assumptions

  • API via HTTP
  • Auth data mostly via HTTP headers
    • Response header: WWW-Authenticate
    • Request header: Authorization
  • Some details are simplified

Basic Auth

2. Response: HTTP 401 Unauthorized

WWW-Authenticate: Basic realm="Hello there!"

1. Request: GET /invoices/

3. Request: GET /invoices/

Authorization: Basic QWxhZGRpbjpPcGVuU2VzYW1l

4. Response: HTTP 200 OK

header_value = base64.encode("username:password")

Basic Auth

  • Very simple
  • Sends password with each request
  • API should be available only over HTTPS
  • Client app should forget the password

Token Auth

2. Response: HTTP 401 Unauthorized

WWW-Authenticate: Token

1. Request: GET /invoices/

5. Request: GET /invoices/

Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b

6. Response: HTTP 200 OK

4. Response: 200 OK

{"token" : "9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b"}

3. Request: POST /obtain-auth-token/

{"username": "john", "password": "secretpass"}

Token Auth

  • Can support multiple client apps
  • Allows for token invalidation
  • Minimise password usage on the wire
  • Tokens usually stored on the server
  • API should be available only over HTTPS

Digest Auth (simplified)

2. Response: HTTP 401 Unauthorized

WWW-Authenticate: Digest nonce="123456"

1. Request: GET /invoices/

4. Response: HTTP 200 OK

3. Request: GET /invoices/

Authorization: Digest username="john" realm="xyz"
token=MD5(nonce, username, realm, URI, password))

Digest Auth

  • Doesn't send plain password over wire
  • Needs plain text password on the server
  • Vulnerable to brute force attack
  • Vulnerable to MITM attack
  • Because of above should be behind HTTPS

Digest Auth + Token Auth

JSON Web Token (JWT)

2. Response: HTTP 401 Unauthorized

WWW-Authenticate: JWT realm="api"

1. Request: GET /invoices/

6. Response: HTTP 200 OK

5. Request: GET /invoices/

Authorization: JWT eyJhbGciOiAiSFMyNTYiLCAidHlwIj

4. Response: 200 OK

{"token" : "eyJhbGciOiAiSFMyNTYiLCAidHlwIj"}

3. Request: POST /obtain-auth-token/

{"username": "john", "password": "secretpass"}

JWT Auth

  • Client app stores token
  • Server does not need to matain tokens
  • Server only generates and validates tokens
  • Stateless
  • JWTs can be signed using a secret
    or a public/private key pairs

JWT Auth

{
  "alg": "HS256",
  "typ": "JWT"
}
{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}
HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

Header

Payload

Signature

OAuth 2.0 / OpenID

  • OAuth 2.0
    • Authentication
    • Authorization
  • OpenID
    • Authentication
  • OpenID Connect
    • Built on the top of OAuth 2.0

OAuth 2.0 / OpenID

  • Three roles
    • Client app
    • Resource server
    • Auth server
  • Client app needs registering
    • Client ID and Secret Token
  • Grants are exchanged for access token

Two scenarios

  • Providing OAuth protocol
    • Follow standards
    • Do not build from scratch
  • Wrapping other services that provide OAuth
    • Keep API Keys and tokens safe 
    • Do not authenticate on external auth token

What's not here?

  • Multi-factor authentication
  • HTTP Signature
  • HTTP HMAC
  • Hawk
  • SAML / SSO

Summary

  • API keys provide extra layer over passwords
  • Auth mechanism should fit to requirements
  • Always use HTTPS
  • You can support multiple methods

Resources

  • https://auth0.com/blog/angularjs-authentication-with-cookies-vs-token/
  • https://jwt.io
  • https://github.com/hueniverse/hawk
  • https://github.com/acquia/http-hmac-spec
  • https://github.com/joyent/node-http-signature/blob/master/http_signing.md
  • https://aaronparecki.com/2012/07/29/2/oauth2-simplified
  • http://www.django-rest-framework.org/api-guide/authentication/
  • https://github.com/juanriaza/django-rest-framework-digestauth

We're looking for speakers!

Join the team!

Thanks!

Questions?

@haxoza

Mechanizm uwierzytelnienia dla twojego API

By Przemek Lewandowski

Mechanizm uwierzytelnienia dla twojego API

  • 3,022