OAuth 2.0: Difference between revisions
(31 intermediate revisions by the same user not shown) | |||
Line 42: | Line 42: | ||
A scope in OAuth is a permission to do something with a protected resource. E.g. access to API, Read/Write, Feature. | A scope in OAuth is a permission to do something with a protected resource. E.g. access to API, Read/Write, Feature. | ||
==Grant Types== | ==Grant Types== | ||
===Types=== | ===Types=== | ||
There are five Grant Types | There are five Grant Types | ||
Line 52: | Line 53: | ||
===Authorization Code Grant Type Flow=== | ===Authorization Code Grant Type Flow=== | ||
The Authorization Code Grant Type is the most commonly used grant type to authorize the Client to access protected data from a Resource Server. | The Authorization Code Grant Type is the most commonly used grant type to authorize the Client to access protected data from a Resource Server.<br> | ||
[[File:Authorization Code Flow.png|600px]]<br> | [[File:Authorization Code Flow.png|600px]]<br> | ||
Line 87: | Line 88: | ||
===Implicit Grant Type Flow=== | ===Implicit Grant Type Flow=== | ||
The Implicit Grant Type is intended to be used by user-agent based clients (Example: SPA), which can’t keep a client secret because all of the application code and storage is easily accessible. | The Implicit Grant Type is intended to be used by user-agent based clients (Example: SPA), which can’t keep a client secret because all of the application code and storage is easily accessible.<br> | ||
[[File:Implicit Flow.png|500px]]<br> | [[File:Implicit Flow.png|500px]]<br> | ||
====Step 1 Authorization Request==== | ====Step 1 Authorization Request==== | ||
Line 103: | Line 104: | ||
*expiry (in seconds) | *expiry (in seconds) | ||
*state | *state | ||
=== | ===Client Credentials Grant Type=== | ||
====Introduction==== | ====Introduction==== | ||
The Refresh Token Grant Flow is specially used to gain new access_token from the Authorization Server by providing the refresh_token to the Token Endpoint.[[File:Refresh Token.png|500px]]<br> | The Client Credentials Grant Type uses the client_id and the client_secret credentials of a Client to authorize and access protected data from a Resource Server.<br> | ||
[[File:Grant Type Client Credientals.png|500px]]<br> | |||
*designed for client applications who are the resource owner | |||
*best for machine-to-machine communication | |||
*requires client authentication | |||
====Step 1 Client requests an access token==== | |||
To receive an access token, the client POSTs an API call to Edge with the values for client ID and client secret obtained from a registered developer app. In addition, the parameter grant_type=client_credentials must be passed as a query parameter. (However, you can configure the OAuthV2 policy to accept this parameter in the request header or body -- see OAuthV2 policy for details).<br> | |||
result = aBase64EncodeFunction(ns4fQc14Zg4hKFCNaSzArVuwszX95X:ZIjFyTsNgQNyxI) // Note the colon separating the two values. | |||
<br> | |||
The result of base64 encoding the above string is: bnM0ZlFjMTRaZzRoS0ZDTmFTekFyVnV3c3pYOTVYOlpJakZ5VHNOZ1FOeXhJOg== | |||
<syntaxHighlight lang=bash> | |||
$ curl -i -H 'Content-Type: application/x-www-form-urlencoded' -X POST 'https://docs-test.apigee.net/oauth/accesstoken' -d 'grant_type=client_credentials&client_id=ns4fQc14Zg4hKFCNaSzArVuwszX95X&client_secret=ZIjFyTsNgQNyxI' | |||
</syntaxHighlight> | |||
Then, make the token request like this: | |||
<syntaxHighlight lang=bash> | |||
$ curl -i -H 'Content-Type: application/x-www-form-urlencoded' -X POST 'https://docs-test.apigee.net/oauth/accesstoken' -d 'grant_type=client_credentials' -H 'Authorization: Basic bnM0ZlFjMTRaZzRoS0ZDTmFTekFyVnV3c3pYOTVYOlpJakZ5VHNOZ1FOeXhJOg==' | |||
</syntaxHighlight> | |||
====Step 2 Validates the credentials==== | |||
====Step 3 Returns a response==== | |||
====Step 4 Client calls the protected API==== | |||
===Refresh Token Grant Type=== | |||
====Introduction==== | |||
The Refresh Token Grant Flow is specially used to gain new access_token from the Authorization Server by providing the refresh_token to the Token Endpoint.<br> | |||
[[File:Refresh Token.png|500px]]<br> | |||
*Can be swapped for new tokens | *Can be swapped for new tokens | ||
*Allow for long-lived access | *Allow for long-lived access | ||
*Highly confidential | *Highly confidential | ||
*User should be made aware that refresh tokens are being requested | *User should be made aware that refresh tokens are being requested | ||
====Step 1 Authorization Request==== | ====Step 1 Authorization Request==== | ||
This is similar to authorization code | This is similar to authorization code | ||
Line 141: | Line 169: | ||
*Refresh Token | *Refresh Token | ||
*Scope | *Scope | ||
===Response Modes=== | ===Response Modes=== | ||
The are three response modes | The are three response modes | ||
Line 153: | Line 182: | ||
*state | *state | ||
If this is the token endpoint they are sent in the post body otherwise in the query string. Usually with a 400 bad request. | If this is the token endpoint they are sent in the post body otherwise in the query string. Usually with a 400 bad request. | ||
==Recommended Flows in OAuth 2.1== | ==Recommended Flows in OAuth 2.1== | ||
Here is probably the present.<br> | Here is probably the present.<br> | ||
[[File:OAuth Flows 2.1.png|400px]] | [[File:OAuth Flows 2.1.png|400px]] | ||
=Best Practices For Native Apps= | |||
==Native Apps== | |||
'''Native Application''' or '''Public clients''' are apps which run on infrastructure not necessarily owned by the company. E.g. Web app, Mobile app and therefore they should not use the Native Flow. | |||
Native Applications | |||
*Can | |||
**Make secure back channel requests | |||
*Can't | |||
**Receive tokens via the browswer | |||
**Keep a secret (and be trusted) | |||
==Proof Key For Code Exchange (PKCE "Pixie")== | |||
This links the authorization request to the token request and is detailed in RFC 7636 | |||
[[File:PKCE Work flow.png|500px]]<br> | |||
==Redirect URI Options== | |||
With the direct on a mobile there are three options list in order of preference | |||
*Private-use URI Schema e.g. nz.co.bibble.linux:/callback | |||
*Claimed https scheme | |||
*Loopback device | |||
==Browsers== | |||
===Embedded User-Agents=== | |||
Try to avoid Embedded User-Agents (Browser). Risk include | |||
*Keystrokes visible | |||
*Cookies exposed | |||
*Authorization process exploitable | |||
*Increased attack surface | |||
*Encourages phishing | |||
Well know identity providers block embedded user agents and authorization server may do the same. | |||
===In-App Browsers=== | |||
This is consider a safer approach as it is in the context application. See RFC 8525 | |||
=Best Practices For Browser Based Apps= | |||
==Browser Based Apps== | |||
This is where code runs in the end user browser. E.g. Single Page App. With Browser Apps | |||
*Network calls are very visible (Dev Tools) | |||
*Replaying is as simple as right clicking | |||
*No Secure storage | |||
*Open to token theft (Biggest risk) | |||
==OAuth in the Browser== | |||
It is recommended we use Authorization Code and PKCE and not use the Implicit Token.<br> | |||
<br> | |||
It you have an API shared across many applications it is recommended to use a backend frontend where the frontend uses an SameSite Cookie. | |||
[[File:OAuth Backend For Frontend.png|400px]] | |||
=OAutu 2.0 Extensions= | |||
==OpenID Connect 1.0 (OIDC)== | |||
OpenID Connect 1.0 (OIDC) Provides Identity built on OAuth 2.0 | |||
**User Info | |||
**Identity Scopes | |||
**Identity Token (Jwt) | |||
==OAuth 2.0 Meta Data== | |||
This is always hosted on /.well-known/oauth-authorization-server and returns the functionality of the server. e.g. | |||
*authorization endpoint | |||
*token endpoint | |||
*token endpoint auth method supported | |||
*scopes_supported or | |||
*response types supported | |||
==OAuth Device Flow== | |||
It defines an authorization flow (Device Flow) to issue access tokens for API clients running on devices with no Web browsers and/or that have limited capability for inputting text, with end user consent.<br> | |||
<br> | |||
The device flow implies the following preconditions.<br> | |||
*User can use devices with Web browsers (e.g. PC, smartphones, tablets) | |||
*Client (e.g. TV, appliances) is a device that can establish an outbound connection to the Internet | |||
*Authorization Server (e.g. streaming service providers) exposes Device Authorization Endpoint to clients | |||
<br> | |||
[[File:OAuth Device Flow.png|500px]] | |||
<br> | |||
*Client (device) sends a device authorization request to device authorization endpoint in Authorization Server. | |||
*Authorization Server replies a device authorization response to Client. The response contains the following main parameters: | |||
**user_code: a value to be submitted from User to Authorization Server. | |||
**device_code: a value for Client to send a token request to Authorization Server. | |||
*Client presents user_code to User. | |||
*The following processes run simultaneously. | |||
**Client sends a token request that includes device_code to Authorization Server. The same requests are periodically made (i.e. polling) to Authorization Server until an access token (or an error) is returned. | |||
**User goes to Authorization Server using an Web browser, authenticates itself, submits user_code and grants access to Client. | |||
*Authorization Server verifies the user_code, issues an access token and sends a token response including the token against the token request that contains the device_code that corresponds to the user_code. | |||
==Microsoft Flow From Work | |||
[[https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow This is the document from work]] |
Latest revision as of 02:26, 16 September 2022
Introduction
History
Previously we used
- XML
- SOAP
- SAML or WS-*
Now we Use
- JSON
- HTTP APIs
- OAuth and OpenID Connect
Credential Sharing
Previously we used to use credential Sharing. E.g. Problems with this are
- We can impersonate the use
- Issues around revocation
- Exposed user credentials
Cookies
Next solution was cookies but CSRF and XSRF attacks were common.
API Key
Next API Key, this works well accept for where the app has no backend. E.g. Single Page App.
- API Keys have no standard
- Expiration management
OAuth 2.0
Features include
- Authorization framework
- Built for HTTP APIs
- Scoped access (User defined what can be used)
- Delegation Protocol
Players include
- Protected Resource (Our API)
- Client (requesting application)
- Resource Owner (the user)
- Authorization Server
Here is the flow for OAuth 2.0
How the API trusts the access token is out of scope for OAuth but if is up to the Protected Resource to do this before sending the response.
Detail
Endpoints
The Protocol endpoint are either
- Authorization Handles all user interaction by the user agent
- Token - This endpoint is for machines only
Scope
A scope in OAuth is a permission to do something with a protected resource. E.g. access to API, Read/Write, Feature.
Grant Types
Types
There are five Grant Types
- Authorization Code Grant Type
- Implicit Grant Type
- Resource Owner Credentials Grant Type (Don't use)
- Client Credentials Grant Type
- Refresh Token Grant
See https://athiththan11.medium.com/oauth-2-grant-types-a-story-guide-582580a3c4c2 for more
Authorization Code Grant Type Flow
The Authorization Code Grant Type is the most commonly used grant type to authorize the Client to access protected data from a Resource Server.
Step 1 - Authorization Request
To make an Authorization request we send
- Response Type
- Client Id
- Redirect Uri
- state (optional)
- scope parameters (optional)
Step 2 - Authorization Response
This redirect to the Url in the request and returns
- code
- state (optionally)
Step 3 - POST Token Request
The parameters include
- Host (e.g. myserver.co.nz)
- Content Type (e.g. x-www-for-urlencoded)
- Authorization (e.g. Basic)
The POST body must include a body with
- grant_type=authorization_code
- code=authorization_code (from step 2)
- redirect_uri=https://client.example.cb
There are two forms of Basic Authentication
- RFC 7617 Base64(client_id + ":" + client_secret)
- RFC 67649 Base64(urlformencode(client_id) + ":" + urlformencode(client_secret))
Step 4 - Token Request Response
If successful we will get
- access_token
- token_type
- expiry (in seconds)
- scope (optional)
Implicit Grant Type Flow
The Implicit Grant Type is intended to be used by user-agent based clients (Example: SPA), which can’t keep a client secret because all of the application code and storage is easily accessible.
Step 1 Authorization Request
For the request we send
- response type
- client id
- redirect_uri
- state
- scope
The redirect is the main defense for abuse
Step 2 Authorization Response
In the response we receive in the Url fragment
- access token
- type type
- expiry (in seconds)
- state
Client Credentials Grant Type
Introduction
The Client Credentials Grant Type uses the client_id and the client_secret credentials of a Client to authorize and access protected data from a Resource Server.
- designed for client applications who are the resource owner
- best for machine-to-machine communication
- requires client authentication
Step 1 Client requests an access token
To receive an access token, the client POSTs an API call to Edge with the values for client ID and client secret obtained from a registered developer app. In addition, the parameter grant_type=client_credentials must be passed as a query parameter. (However, you can configure the OAuthV2 policy to accept this parameter in the request header or body -- see OAuthV2 policy for details).
result = aBase64EncodeFunction(ns4fQc14Zg4hKFCNaSzArVuwszX95X:ZIjFyTsNgQNyxI) // Note the colon separating the two values.
The result of base64 encoding the above string is: bnM0ZlFjMTRaZzRoS0ZDTmFTekFyVnV3c3pYOTVYOlpJakZ5VHNOZ1FOeXhJOg==
$ curl -i -H 'Content-Type: application/x-www-form-urlencoded' -X POST 'https://docs-test.apigee.net/oauth/accesstoken' -d 'grant_type=client_credentials&client_id=ns4fQc14Zg4hKFCNaSzArVuwszX95X&client_secret=ZIjFyTsNgQNyxI'
Then, make the token request like this:
$ curl -i -H 'Content-Type: application/x-www-form-urlencoded' -X POST 'https://docs-test.apigee.net/oauth/accesstoken' -d 'grant_type=client_credentials' -H 'Authorization: Basic bnM0ZlFjMTRaZzRoS0ZDTmFTekFyVnV3c3pYOTVYOlpJakZ5VHNOZ1FOeXhJOg=='
Step 2 Validates the credentials
Step 3 Returns a response
Step 4 Client calls the protected API
Refresh Token Grant Type
Introduction
The Refresh Token Grant Flow is specially used to gain new access_token from the Authorization Server by providing the refresh_token to the Token Endpoint.
- Can be swapped for new tokens
- Allow for long-lived access
- Highly confidential
- User should be made aware that refresh tokens are being requested
Step 1 Authorization Request
This is similar to authorization code
- response type
- client id
- redirect uri
- state (optional)
- scope (optional)
A common scope used is offline_access which indicates the usage of this token.
Step 2 Authorization Response (token response)
The response will contain
- access token
- token type
- expiry (in seconds)
- refresh token
- scope
Step 3 Refresh Token Request (POST)
In this we send to the token endpoint a request with
- Host
- Authorization
- Content type
And parameters
- grant_type=refresh_token
- refresh_token
- scope
Step 4 Refresh Token Response
If successful we receive
- Access Token
- Token type
- Expiry (in seconds)
- Refresh Token
- Scope
Response Modes
The are three response modes
- Query String
- Hash Fragment
- Form Post (Recommended)
Errors
If there are errors the server may return
- error
- error description
- error url
- state
If this is the token endpoint they are sent in the post body otherwise in the query string. Usually with a 400 bad request.
Recommended Flows in OAuth 2.1
Best Practices For Native Apps
Native Apps
Native Application or Public clients are apps which run on infrastructure not necessarily owned by the company. E.g. Web app, Mobile app and therefore they should not use the Native Flow. Native Applications
- Can
- Make secure back channel requests
- Can't
- Receive tokens via the browswer
- Keep a secret (and be trusted)
Proof Key For Code Exchange (PKCE "Pixie")
This links the authorization request to the token request and is detailed in RFC 7636
Redirect URI Options
With the direct on a mobile there are three options list in order of preference
- Private-use URI Schema e.g. nz.co.bibble.linux:/callback
- Claimed https scheme
- Loopback device
Browsers
Embedded User-Agents
Try to avoid Embedded User-Agents (Browser). Risk include
- Keystrokes visible
- Cookies exposed
- Authorization process exploitable
- Increased attack surface
- Encourages phishing
Well know identity providers block embedded user agents and authorization server may do the same.
In-App Browsers
This is consider a safer approach as it is in the context application. See RFC 8525
Best Practices For Browser Based Apps
Browser Based Apps
This is where code runs in the end user browser. E.g. Single Page App. With Browser Apps
- Network calls are very visible (Dev Tools)
- Replaying is as simple as right clicking
- No Secure storage
- Open to token theft (Biggest risk)
OAuth in the Browser
It is recommended we use Authorization Code and PKCE and not use the Implicit Token.
It you have an API shared across many applications it is recommended to use a backend frontend where the frontend uses an SameSite Cookie.
OAutu 2.0 Extensions
OpenID Connect 1.0 (OIDC)
OpenID Connect 1.0 (OIDC) Provides Identity built on OAuth 2.0
- User Info
- Identity Scopes
- Identity Token (Jwt)
OAuth 2.0 Meta Data
This is always hosted on /.well-known/oauth-authorization-server and returns the functionality of the server. e.g.
- authorization endpoint
- token endpoint
- token endpoint auth method supported
- scopes_supported or
- response types supported
OAuth Device Flow
It defines an authorization flow (Device Flow) to issue access tokens for API clients running on devices with no Web browsers and/or that have limited capability for inputting text, with end user consent.
The device flow implies the following preconditions.
- User can use devices with Web browsers (e.g. PC, smartphones, tablets)
- Client (e.g. TV, appliances) is a device that can establish an outbound connection to the Internet
- Authorization Server (e.g. streaming service providers) exposes Device Authorization Endpoint to clients
- Client (device) sends a device authorization request to device authorization endpoint in Authorization Server.
- Authorization Server replies a device authorization response to Client. The response contains the following main parameters:
- user_code: a value to be submitted from User to Authorization Server.
- device_code: a value for Client to send a token request to Authorization Server.
- Client presents user_code to User.
- The following processes run simultaneously.
- Client sends a token request that includes device_code to Authorization Server. The same requests are periodically made (i.e. polling) to Authorization Server until an access token (or an error) is returned.
- User goes to Authorization Server using an Web browser, authenticates itself, submits user_code and grants access to Client.
- Authorization Server verifies the user_code, issues an access token and sends a token response including the token against the token request that contains the device_code that corresponds to the user_code.
==Microsoft Flow From Work [This is the document from work]