Background
- Authenticating a third-party application with credentials
- credentials (passwords) must be stored in third-party application
- no restriction of third-party application access – because of credentials
Roles
- Resource owner: entity granting access to a resource, could be an end-user
- Resource server: providing the protected resource (data), accepting
- Client application: e.g. an application making
- Authorization server: authorizing the client application to access the resource data by issuing
Resource Server and Authorization Server can be the same server. Interaction is not specified by OAuth2!
Flow
+--------+ +---------------+ | |--(A)- Authorization Request ->| Resource | | | | Owner | | |<-(B)-- Authorization Grant ---| | | | +---------------+ | | | | +---------------+ | |--(C)-- Authorization Grant -->| Authorization | | Client | | Server | | |<-(D)----- Access Token -------| | | | +---------------+ | | | | +---------------+ | |--(E)----- Access Token ------>| Resource | | | | Server | | |<-(F)--- Protected Resource ---| | +--------+ +---------------+ (from https://tools.ietf.org/html/rfc6749#section-1.2)
Authorization Grant Types
How to authorization itself is done:
- Authorization code: 3rd web or native – if all roles are existing
- Password: 1st party (application talking to own api)
- Client credentials: application (no user)
- Implicit: 3rd party JS app -> hard to secure, since public source code
Example: Password Grant
like Twitter with a login form
- user -> application: username/password
- application -> authorization server: “give me token please”
POST /token Accept: application/json Content-Type: application/json { grant_type: password client_id: mywebsite client_secret: "abcdef" username: "bob" password: "123456" }
- authorization server -> application: token (response)
{ access_token: fcbsdvukcsdvhbdf, expires_in: 3600, token_type: Bearer, scope: null, refresh_token: dewdjelsfbhsadvds }
- application -> api: message with token
- in every request token must be validated!
- => authorization and api separated endpoints (but could be same application)
Example: Authorisation code
- user -> application: login
- application -> user: get me a token
- user -> authorisation server: login
- authorisation server -> user: do you trust this app
- user -> authorisation server: yes!
- authorisation server -> application : auth code
- application -> authorisation server: give me a token
POST /token Accept: application/json Content-Type: application/json { grant_type: authorization_code client_id: myclient client_secret: "abcdef" code: "hudiencsduivbajvnfsdhvbdsnvskdubvkdku" }
- authorisation server -> application : token
- application -> api:messages with token
Tokens
HTTP Header: Authorization: Bearer {some_string_here}
JWT bearer tokens (“jot”)
- cryptographically signed block of data
- parts: header, payload, signature
- algorithm can be found in specification => use well-tested modules and do not implement it on your own
- no database needed for verification => in memory check
=> structure for “some_string_here”
Refresh token
access tokens expire quickly => refresh token, so that your user keeps being logged in
References
- https://oauth.net/2/
- https://jwt.io/
- Specification:
- Rob Allen on code.talks 2017 incl. a basic tutorial for implementation in PHP