The OAuth 2.0 Authorization Framework

The OAuth 2.0 authorization framework enables a third-party application to obtain limited access to an HTTP service, either on behalf of a resource owner by orchestrating an approval interaction between the resource owner and the HTTP service, or by allowing the third-party application to obtain access on its own behalf.

The title of RFC6749 is The OAuth 2.0 Authorization Framework. OAuth 2.0 is a framework instead of a protocol(unlike OAuth 1.0). The concept of framework makes OAuth 2.0 very unique. Being a framework means people can create more RFCs upon it, can extend it with their own needs. With so many years passed, what you know about OAuth 2.0 MAY be wrong or not accurate. There are lots of RFCs should be taken into account in OAuth 2.0, which requires a very flexible design of an OAuth 2.0 library. And this is the principle design in Authlib, Authlib is very flexible.

How OAuth 2.0 works

Roles in OAuth 2.0

The above image shows how OAuth 2.0 works. There are four roles in the OAuth 2.0 flow. Which are:

1. Resource Owner

Usually, they are the customers on the website, e.g. users on Facebook are resource owners. Why it is called resource owner? The websites like Facebook are platforms, content are created by the users on the platform, which means the resources are belong to the users on that platform.

2. Client

A client is created by a developer which can obtain a resource owner’s access token under resource owner’s approval. Later, it can access the resource owner’s information or post something for the resource owner. For instance, the mobile Facebook App is a client, the Google logins on some websites are clients too.

For your information, the developer who created a client is also a resource owner.

3. Authorization Server

The authorization server is used by clients to obtain access tokens, which means the authorization server can issue tokens. It may also have a login page so that resource owners can login.

The main purpose of the authorization server is issuing tokens, login feature can be optional if you have another account server.

4. Resource Servers

The resource servers (or server) are the APIs that a client can fetch or post something with the given access token issued by authorization server. Note that you may combine resource servers and authorization server into one big server. But it gets bigger and bigger, you will need to separate them.

For instance, it was https://example.com/oauth/token and https://example.com/api/xxx but later it will become something like https://account.example.com and https://api.example.com.

Obtain an Access Token

Client can obtain an access token with the resource owner’s approval. A common flow of obtaining an access token:

  1. client redirect user to authorization server
  2. user approve this authorization
  3. authorization server redirect back to client
  4. client use the code to obtain an access token from authorization server

This is a very common authorization flow used by most OAuth 2.0 provider. It is called authorization_code grant type flow. Get more information on grant types below.

No matter what grant type the client is using, when obtaining an access token, a client MUST authenticate itself.

Token Endpoint Auth Methods

A token endpoint auth method is a certain method to authenticate a client at the token endpoint. For example:

POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA
&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb

That Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW is used to authenticate the client. Use of a Basic Authorization in header is called client_secret_basic.

RFC6749 has no clarification for token endpoint client authentication methods, but there are some use cases in RFC6749, except that they have no names. The names are defined by RFC7591, which are:

  • none: The client is a public client which means it has no client_secret

    POST /token HTTP/1.1
    Host: server.example.com
    Content-Type: application/x-www-form-urlencoded
    
    grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA
    &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb
    &client_id=s6BhdRkqt3
    
  • client_secret_post: The client uses the HTTP POST parameters

    POST /token HTTP/1.1
    Host: server.example.com
    Content-Type: application/x-www-form-urlencoded
    
    grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA
    &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb
    &client_id=s6BhdRkqt3&client_secret=gX1fBat3bV
    
  • client_secret_basic: The client uses HTTP Basic Authorization

    POST /token HTTP/1.1
    Host: server.example.com
    Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
    Content-Type: application/x-www-form-urlencoded
    
    grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA
    &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb
    

It is also possible to add other client authentication methods, read more in Using JWTs for Client Authentication.

API References

Here are the API references for developers. For framework level interfaces, check:

  1. Flask: Flask OAuth 2.0 Server.
  2. Django: not ready yet.

Servers

class authlib.specs.rfc6749.AuthorizationServer(query_client, generate_token, save_token, **config)

Authorization server that handles Authorization Endpoint and Token Endpoint.

Parameters:
  • query_client – A function to get client by client_id. The client model class MUST implement the methods described by ClientMixin.
  • token_generator – A method to generate tokens.
create_authorization_response(request=None, grant_user=None)

Validate authorization request and create authorization response.

Parameters:
  • request – OAuth2Request instance.
  • grant_user – if granted, it is resource owner. If denied, it is None.
Returns:

Response

create_token_response(request=None)

Validate token request and create token response.

Parameters:request – OAuth2Request instance
get_authorization_grant(request)

Find the authorization grant for current request.

Parameters:request – OAuth2Request instance.
Returns:grant instance
get_token_grant(request)

Find the token grant for current request.

Parameters:request – OAuth2Request instance.
Returns:grant instance
register_client_auth_method(method, func)

Add more client auth method. The default methods are:

  • none: The client is a public client and does not have a client secret
  • client_secret_post: The client uses the HTTP POST parameters
  • client_secret_basic: The client uses HTTP Basic
Parameters:
  • method – Name of the Auth method
  • func – Function to authenticate the client

The auth method accept two parameters: query_client and request, an example for this method:

def authenticate_client_via_custom(query_client, request):
    client_id = request.headers['X-Client-Id']
    client = query_client(client_id)
    do_some_validation(client)
    return client

authorization_server.register_client_auth_method(
    'custom', authenticate_client_via_custom)
register_grant(grant_cls)

Register a grant class into the endpoint registry. Developers can implement the grants in authlib.specs.rfc6749.grants and register with this method:

class AuthorizationCodeGrant(grants.AuthorizationCodeGrant):
    def authenticate_user(self, credential):
        # ...

authorization_server.register_grant(AuthorizationCodeGrant)
Parameters:grant_cls – a grant class.
class authlib.specs.rfc6749.ResourceProtector

Client Model

class authlib.specs.rfc6749.ClientMixin

Implementation of OAuth 2 Client described in Section 2 with some methods to help validation. A client has at least these information:

  • client_id: A string represents client identifier.
  • client_secret: A string represents client password.
  • token_endpoint_auth_method: A way to authenticate client at token
    endpoint.
check_client_secret(client_secret)

Check client_secret matching with the client. For instance, in the client table, the column is called client_secret:

def check_client_secret(self, client_secret):
    return self.client_secret == client_secret
Parameters:client_secret – A string of client secret
Returns:bool
check_grant_type(grant_type)

Validate if the client can handle the given grant_type. There are four grant types defined by RFC6749:

  • authorization_code
  • implicit
  • client_credentials
  • password

For instance, there is a allowed_grant_types column in your client:

def check_grant_type(self, grant_type):
    return grant_type in self.grant_types
Parameters:grant_type – the requested grant_type string.
Returns:bool
check_redirect_uri(redirect_uri)

Validate redirect_uri parameter in Authorization Endpoints. For instance, in the client table, there is an allowed_redirect_uris column:

def check_redirect_uri(self, redirect_uri):
    return redirect_uri in self.allowed_redirect_uris
Parameters:redirect_uri – A URL string for redirecting.
Returns:bool
check_requested_scopes(scopes)

Validate if the request scopes are supported by this client. It can always be True. For instance, there is a scope column:

def check_requested_scopes(self, scopes):
    return set(self.scope.split()).issuperset(scopes)
Parameters:scopes – the requested scopes set.
Returns:bool
check_response_type(response_type)

Validate if the client can handle the given response_type. There are two response types defined by RFC6749: code and token. For instance, there is a allowed_response_types column in your client:

def check_response_type(self, response_type):
    return response_type in self.response_types
Parameters:response_type – the requested response_type string.
Returns:bool
check_token_endpoint_auth_method(method)

Check client token_endpoint_auth_method defined via RFC7591. Values defined by this specification are:

  • “none”: The client is a public client as defined in OAuth 2.0,
    and does not have a client secret.
  • “client_secret_post”: The client uses the HTTP POST parameters
    as defined in OAuth 2.0
  • “client_secret_basic”: The client uses HTTP Basic as defined in
    OAuth 2.0
get_default_redirect_uri()

A method to get client default redirect_uri. For instance, the database table for client has a column called default_redirect_uri:

def get_default_redirect_uri(self):
    return self.default_redirect_uri
Returns:A URL string
has_client_secret()

A method returns that if the client has client_secret value. If the value is in client_secret column:

def has_client_secret(self):
    return bool(self.client_secret)
Returns:bool

Errors

class authlib.specs.rfc6749.OAuth2Error(description=None, uri=None, status_code=None, state=None)
get_body()

Get a list of body.

authlib.specs.rfc6749.register_error_uri(error, error_uri)

Register error_uri for each error code. When raise an OAuth2Error without error_uri, it will use the URI in this registry:

register_error_uri('invalid_client', 'https://example.com/errors#invalid-client')
Parameters:
  • error – OAuth 2 error code.
  • error_uri – A human-readable web page with information about the error.
class authlib.specs.rfc6749.InsecureTransportError(description=None, uri=None, status_code=None, state=None)
classmethod check(uri)

Check and raise InsecureTransportError with the given URI.

class authlib.specs.rfc6749.InvalidRequestError(description=None, uri=None, status_code=None, state=None)

The request is missing a required parameter, includes an unsupported parameter value (other than grant type), repeats a parameter, includes multiple credentials, utilizes more than one mechanism for authenticating the client, or is otherwise malformed.

https://tools.ietf.org/html/rfc6749#section-5.2

class authlib.specs.rfc6749.InvalidClientError(description=None, uri=None, status_code=None, state=None)

Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method). The authorization server MAY return an HTTP 401 (Unauthorized) status code to indicate which HTTP authentication schemes are supported. If the client attempted to authenticate via the “Authorization” request header field, the authorization server MUST respond with an HTTP 401 (Unauthorized) status code and include the “WWW-Authenticate” response header field matching the authentication scheme used by the client.

https://tools.ietf.org/html/rfc6749#section-5.2

class authlib.specs.rfc6749.InvalidGrantError(description=None, uri=None, status_code=None, state=None)

The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.

https://tools.ietf.org/html/rfc6749#section-5.2

class authlib.specs.rfc6749.UnauthorizedClientError(description=None, uri=None, status_code=None, state=None)

The authenticated client is not authorized to use this authorization grant type.

https://tools.ietf.org/html/rfc6749#section-5.2

class authlib.specs.rfc6749.UnsupportedGrantTypeError(description=None, uri=None, status_code=None, state=None)

The authorization grant type is not supported by the authorization server.

https://tools.ietf.org/html/rfc6749#section-5.2

class authlib.specs.rfc6749.InvalidScopeError(description=None, uri=None, status_code=None, state=None)

The requested scope is invalid, unknown, malformed, or exceeds the scope granted by the resource owner.

https://tools.ietf.org/html/rfc6749#section-5.2

class authlib.specs.rfc6749.AccessDeniedError(description=None, uri=None, status_code=None, state=None)

The resource owner or authorization server denied the request.

Used in authorization endpoint for “code” and “implicit”. Defined in Section 4.1.2.1.

Grant Types

class authlib.specs.rfc6749.grants.AuthorizationCodeGrant(request, server)

The authorization code grant type is used to obtain both access tokens and refresh tokens and is optimized for confidential clients. Since this is a redirection-based flow, the client must be capable of interacting with the resource owner’s user-agent (typically a web browser) and capable of receiving incoming requests (via redirection) from the authorization server:

+----------+
| Resource |
|   Owner  |
|          |
+----------+
     ^
     |
    (B)
+----|-----+          Client Identifier      +---------------+
|         -+----(A)-- & Redirection URI ---->|               |
|  User-   |                                 | Authorization |
|  Agent  -+----(B)-- User authenticates --->|     Server    |
|          |                                 |               |
|         -+----(C)-- Authorization Code ---<|               |
+-|----|---+                                 +---------------+
  |    |                                         ^      v
 (A)  (C)                                        |      |
  |    |                                         |      |
  ^    v                                         |      |
+---------+                                      |      |
|         |>---(D)-- Authorization Code ---------'      |
|  Client |          & Redirection URI                  |
|         |                                             |
|         |<---(E)----- Access Token -------------------'
+---------+       (w/ Optional Refresh Token)
AUTHORIZATION_ENDPOINT = True

authorization_code grant type has authorization endpoint

TOKEN_ENDPOINT = True

authorization_code grant type has token endpoint

TOKEN_ENDPOINT_AUTH_METHODS = ['client_secret_basic', 'client_secret_post', 'none']

Allowed client auth methods for token endpoint

validate_authorization_request()

The client constructs the request URI by adding the following parameters to the query component of the authorization endpoint URI using the “application/x-www-form-urlencoded” format. Per Section 4.1.1.

response_type
REQUIRED. Value MUST be set to “code”.
client_id
REQUIRED. The client identifier as described in Section 2.2.
redirect_uri
OPTIONAL. As described in Section 3.1.2.
scope
OPTIONAL. The scope of the access request as described by Section 3.3.
state
RECOMMENDED. An opaque value used by the client to maintain state between the request and callback. The authorization server includes this value when redirecting the user-agent back to the client. The parameter SHOULD be used for preventing cross-site request forgery as described in Section 10.12.

The client directs the resource owner to the constructed URI using an HTTP redirection response, or by other means available to it via the user-agent.

For example, the client directs the user-agent to make the following HTTP request using TLS (with extra line breaks for display purposes only):

GET /authorize?response_type=code&client_id=s6BhdRkqt3&state=xyz
&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1
Host: server.example.com

The authorization server validates the request to ensure that all required parameters are present and valid. If the request is valid, the authorization server authenticates the resource owner and obtains an authorization decision (by asking the resource owner or by establishing approval via other means).

create_authorization_response(grant_user)

If the resource owner grants the access request, the authorization server issues an authorization code and delivers it to the client by adding the following parameters to the query component of the redirection URI using the “application/x-www-form-urlencoded” format. Per Section 4.1.2.

code
REQUIRED. The authorization code generated by the authorization server. The authorization code MUST expire shortly after it is issued to mitigate the risk of leaks. A maximum authorization code lifetime of 10 minutes is RECOMMENDED. The client MUST NOT use the authorization code more than once. If an authorization code is used more than once, the authorization server MUST deny the request and SHOULD revoke (when possible) all tokens previously issued based on that authorization code. The authorization code is bound to the client identifier and redirection URI.
state
REQUIRED if the “state” parameter was present in the client authorization request. The exact value received from the client.

For example, the authorization server redirects the user-agent by sending the following HTTP response.

HTTP/1.1 302 Found
Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA
       &state=xyz
Parameters:grant_user – if resource owner granted the request, pass this resource owner, otherwise pass None.
Returns:(status_code, body, headers)
validate_token_request()

The client makes a request to the token endpoint by sending the following parameters using the “application/x-www-form-urlencoded” format per Section 4.1.3:

grant_type
REQUIRED. Value MUST be set to “authorization_code”.
code
REQUIRED. The authorization code received from the authorization server.
redirect_uri
REQUIRED, if the “redirect_uri” parameter was included in the authorization request as described in Section 4.1.1, and their values MUST be identical.
client_id
REQUIRED, if the client is not authenticating with the authorization server as described in Section 3.2.1.

If the client type is confidential or the client was issued client credentials (or assigned other authentication requirements), the client MUST authenticate with the authorization server as described in Section 3.2.1.

For example, the client makes the following HTTP request using TLS:

POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA
&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb
create_token_response()

If the access token request is valid and authorized, the authorization server issues an access token and optional refresh token as described in Section 5.1. If the request client authentication failed or is invalid, the authorization server returns an error response as described in Section 5.2. Per Section 4.1.4.

An example successful response:

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache

{
    "access_token":"2YotnFZFEjr1zCsicMWpAA",
    "token_type":"example",
    "expires_in":3600,
    "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
    "example_parameter":"example_value"
}
Returns:(status_code, body, headers)
create_authorization_code(client, grant_user, request)

Save authorization_code for later use. Developers should implement it in subclass. Here is an example:

from authlib.common.security import generate_token

def create_authorization_code(self, client, request):
    code = generate_token(48)
    item = AuthorizationCode(
        code=code,
        client_id=client.client_id,
        redirect_uri=request.redirect_uri,
        scope=request.scope,
        user_id=grant_user.get_user_id(),
    )
    item.save()
    return code
Parameters:
  • client – the client that requesting the token.
  • grant_user – the resource owner that grant the permission.
  • request – OAuth2Request instance.
Returns:

code string

parse_authorization_code(code, client)

Get authorization_code from previously savings. Developers should implement it in subclass:

def parse_authorization_code(self, code, client):
    return Authorization.get(code=code, client_id=client.client_id)
Parameters:
  • code – a string represent the code.
  • client – client related to this code.
Returns:

authorization_code object

delete_authorization_code(authorization_code)

Delete authorization code from database or cache. Developers should implement it in subclass, e.g.:

def delete_authorization_code(self, authorization_code):
    authorization_code.delete()
Parameters:authorization_code – the instance of authorization_code
authenticate_user(authorization_code)

Authenticate the user related to this authorization_code. Developers should implement this method in subclass, e.g.:

def authenticate_user(self, authorization_code):
    return User.query.get(authorization_code.user_id)
Parameters:authorization_code – AuthorizationCode object
Returns:user
class authlib.specs.rfc6749.grants.ImplicitGrant(request, server)

The implicit grant type is used to obtain access tokens (it does not support the issuance of refresh tokens) and is optimized for public clients known to operate a particular redirection URI. These clients are typically implemented in a browser using a scripting language such as JavaScript.

Since this is a redirection-based flow, the client must be capable of interacting with the resource owner’s user-agent (typically a web browser) and capable of receiving incoming requests (via redirection) from the authorization server.

Unlike the authorization code grant type, in which the client makes separate requests for authorization and for an access token, the client receives the access token as the result of the authorization request.

The implicit grant type does not include client authentication, and relies on the presence of the resource owner and the registration of the redirection URI. Because the access token is encoded into the redirection URI, it may be exposed to the resource owner and other applications residing on the same device:

+----------+
| Resource |
|  Owner   |
|          |
+----------+
     ^
     |
    (B)
+----|-----+          Client Identifier     +---------------+
|         -+----(A)-- & Redirection URI --->|               |
|  User-   |                                | Authorization |
|  Agent  -|----(B)-- User authenticates -->|     Server    |
|          |                                |               |
|          |<---(C)--- Redirection URI ----<|               |
|          |          with Access Token     +---------------+
|          |            in Fragment
|          |                                +---------------+
|          |----(D)--- Redirection URI ---->|   Web-Hosted  |
|          |          without Fragment      |     Client    |
|          |                                |    Resource   |
|     (F)  |<---(E)------- Script ---------<|               |
|          |                                +---------------+
+-|--------+
  |    |
 (A)  (G) Access Token
  |    |
  ^    v
+---------+
|         |
|  Client |
|         |
+---------+
AUTHORIZATION_ENDPOINT = True

authorization_code grant type has authorization endpoint

TOKEN_ENDPOINT_AUTH_METHODS = ['none']

Allowed client auth methods for token endpoint

validate_authorization_request()

The client constructs the request URI by adding the following parameters to the query component of the authorization endpoint URI using the “application/x-www-form-urlencoded” format. Per Section 4.2.1.

response_type
REQUIRED. Value MUST be set to “token”.
client_id
REQUIRED. The client identifier as described in Section 2.2.
redirect_uri
OPTIONAL. As described in Section 3.1.2.
scope
OPTIONAL. The scope of the access request as described by Section 3.3.
state
RECOMMENDED. An opaque value used by the client to maintain state between the request and callback. The authorization server includes this value when redirecting the user-agent back to the client. The parameter SHOULD be used for preventing cross-site request forgery as described in Section 10.12.

The client directs the resource owner to the constructed URI using an HTTP redirection response, or by other means available to it via the user-agent.

For example, the client directs the user-agent to make the following HTTP request using TLS:

GET /authorize?response_type=token&client_id=s6BhdRkqt3&state=xyz
&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1
Host: server.example.com
create_authorization_response(grant_user)

If the resource owner grants the access request, the authorization server issues an access token and delivers it to the client by adding the following parameters to the fragment component of the redirection URI using the “application/x-www-form-urlencoded” format. Per Section 4.2.2.

access_token
REQUIRED. The access token issued by the authorization server.
token_type
REQUIRED. The type of the token issued as described in Section 7.1. Value is case insensitive.
expires_in
RECOMMENDED. The lifetime in seconds of the access token. For example, the value “3600” denotes that the access token will expire in one hour from the time the response was generated. If omitted, the authorization server SHOULD provide the expiration time via other means or document the default value.
scope
OPTIONAL, if identical to the scope requested by the client; otherwise, REQUIRED. The scope of the access token as described by Section 3.3.
state
REQUIRED if the “state” parameter was present in the client authorization request. The exact value received from the client.

The authorization server MUST NOT issue a refresh token.

For example, the authorization server redirects the user-agent by sending the following HTTP response:

HTTP/1.1 302 Found
Location: http://example.com/cb#access_token=2YotnFZFEjr1zCsicMWpAA
       &state=xyz&token_type=example&expires_in=3600

Developers should note that some user-agents do not support the inclusion of a fragment component in the HTTP “Location” response header field. Such clients will require using other methods for redirecting the client than a 3xx redirection response – for example, returning an HTML page that includes a ‘continue’ button with an action linked to the redirection URI.

Parameters:grant_user – if resource owner granted the request, pass this resource owner, otherwise pass None.
Returns:(status_code, body, headers)
class authlib.specs.rfc6749.grants.ResourceOwnerPasswordCredentialsGrant(request, server)

The resource owner password credentials grant type is suitable in cases where the resource owner has a trust relationship with the client, such as the device operating system or a highly privileged

application. The authorization server should take special care when enabling this grant type and only allow it when other flows are not viable.

This grant type is suitable for clients capable of obtaining the resource owner’s credentials (username and password, typically using an interactive form). It is also used to migrate existing clients using direct authentication schemes such as HTTP Basic or Digest authentication to OAuth by converting the stored credentials to an access token:

+----------+
| Resource |
|  Owner   |
|          |
+----------+
    v
    |    Resource Owner
   (A) Password Credentials
    |
    v
+---------+                                  +---------------+
|         |>--(B)---- Resource Owner ------->|               |
|         |         Password Credentials     | Authorization |
| Client  |                                  |     Server    |
|         |<--(C)---- Access Token ---------<|               |
|         |    (w/ Optional Refresh Token)   |               |
+---------+                                  +---------------+
TOKEN_ENDPOINT = True

authorization_code grant type has token endpoint

validate_token_request()

The client makes a request to the token endpoint by adding the following parameters using the “application/x-www-form-urlencoded” format per Appendix B with a character encoding of UTF-8 in the HTTP request entity-body:

grant_type
REQUIRED. Value MUST be set to “password”.
username
REQUIRED. The resource owner username.
password
REQUIRED. The resource owner password.
scope
OPTIONAL. The scope of the access request as described by Section 3.3.

If the client type is confidential or the client was issued client credentials (or assigned other authentication requirements), the client MUST authenticate with the authorization server as described in Section 3.2.1.

For example, the client makes the following HTTP request using transport-layer security (with extra line breaks for display purposes only):

POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded

grant_type=password&username=johndoe&password=A3ddj3w
create_token_response()

If the access token request is valid and authorized, the authorization server issues an access token and optional refresh token as described in Section 5.1. If the request failed client authentication or is invalid, the authorization server returns an error response as described in Section 5.2.

An example successful response:

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache

{
    "access_token":"2YotnFZFEjr1zCsicMWpAA",
    "token_type":"example",
    "expires_in":3600,
    "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
    "example_parameter":"example_value"
}
Returns:(status_code, body, headers)
authenticate_user(username, password)

validate the resource owner password credentials using its existing password validation algorithm:

def authenticate_user(self, username, password):
    user = get_user_by_username(username)
    if user.check_password(password):
       return user
class authlib.specs.rfc6749.grants.ClientCredentialsGrant(request, server)

The client can request an access token using only its client credentials (or other supported means of authentication) when the client is requesting access to the protected resources under its control, or those of another resource owner that have been previously arranged with the authorization server.

The client credentials grant type MUST only be used by confidential clients:

+---------+                                  +---------------+
|         |                                  |               |
|         |>--(A)- Client Authentication --->| Authorization |
| Client  |                                  |     Server    |
|         |<--(B)---- Access Token ---------<|               |
|         |                                  |               |
+---------+                                  +---------------+

https://tools.ietf.org/html/rfc6749#section-4.4

TOKEN_ENDPOINT = True

authorization_code grant type has token endpoint

validate_token_request()

The client makes a request to the token endpoint by adding the following parameters using the “application/x-www-form-urlencoded” format per Appendix B with a character encoding of UTF-8 in the HTTP request entity-body:

grant_type
REQUIRED. Value MUST be set to “client_credentials”.
scope
OPTIONAL. The scope of the access request as described by Section 3.3.

The client MUST authenticate with the authorization server as described in Section 3.2.1.

For example, the client makes the following HTTP request using transport-layer security (with extra line breaks for display purposes only):

POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials

The authorization server MUST authenticate the client.

create_token_response()

If the access token request is valid and authorized, the authorization server issues an access token as described in Section 5.1. A refresh token SHOULD NOT be included. If the request failed client authentication or is invalid, the authorization server returns an error response as described in Section 5.2.

An example successful response:

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache

{
    "access_token":"2YotnFZFEjr1zCsicMWpAA",
    "token_type":"example",
    "expires_in":3600,
    "example_parameter":"example_value"
}
Returns:(status_code, body, headers)
class authlib.specs.rfc6749.grants.RefreshTokenGrant(request, server)

A special grant endpoint for refresh_token grant_type. Refreshing an Access Token per Section 6.

TOKEN_ENDPOINT = True

authorization_code grant type has token endpoint

validate_token_request()

If the authorization server issued a refresh token to the client, the client makes a refresh request to the token endpoint by adding the following parameters using the “application/x-www-form-urlencoded” format per Appendix B with a character encoding of UTF-8 in the HTTP request entity-body, per Section 6:

grant_type
REQUIRED. Value MUST be set to “refresh_token”.
refresh_token
REQUIRED. The refresh token issued to the client.
scope
OPTIONAL. The scope of the access request as described by Section 3.3. The requested scope MUST NOT include any scope not originally granted by the resource owner, and if omitted is treated as equal to the scope originally granted by the resource owner.

For example, the client makes the following HTTP request using transport-layer security (with extra line breaks for display purposes only):

POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA
create_token_response()

If valid and authorized, the authorization server issues an access token as described in Section 5.1. If the request failed verification or is invalid, the authorization server returns an error response as described in Section 5.2.

authenticate_refresh_token(refresh_token)

Get token information with refresh_token string. Developers should implement this method in subclass:

def authenticate_refresh_token(self, refresh_token):
    item = Token.get(refresh_token=refresh_token)
    if item and not item.is_refresh_token_expired():
        return item
Parameters:refresh_token – The refresh token issued to the client
Returns:token
authenticate_user(credential)

Authenticate the user related to this credential. Developers should implement this method in subclass:

def authenticate_user(self, credential):
    return User.query.get(credential.user_id)
Parameters:credential – Token object
Returns:user