Client Class
This is the main API for oauth2 client.
Its methods define and document parameters mentioned in OAUTH2 RFC 6749.
- Inheritance
-
Client
Constructor
Client(server_configuration, client_id, on_obtaining_tokens=<function Client.<lambda>>, on_removing_rt=<function Client.<lambda>>, on_updating_rt=<function Client.<lambda>>, **kwargs)
Parameters
- server_configuration
- client_id
- on_obtaining_tokens
- on_removing_rt
- on_updating_rt
Methods
| build_auth_request_uri |
Generate an authorization uri to be visited by resource owner. Parameters are the same as another method initiate_auth_code_flow, whose functionality is a superset of this method. |
| initiate_auth_code_flow |
Initiate an auth code flow. Later when the response reaches your redirect_uri, you can use obtain_token_by_auth_code_flow to complete the authentication/authorization. This method also provides PKCE protection automatically. |
| initiate_device_flow |
Initiate a device flow. Returns the data defined in Device Flow specs. https://tools.ietf.org/html/draft-ietf-oauth-device-flow-12#section-3.2 You should then orchestrate the User Interaction as defined in here https://tools.ietf.org/html/draft-ietf-oauth-device-flow-12#section-3.3 And possibly here https://tools.ietf.org/html/draft-ietf-oauth-device-flow-12#section-3.3.1 |
| obtain_token_by_assertion |
This method implements Assertion Framework for OAuth2 (RFC 7521). See details at https://tools.ietf.org/html/rfc7521#section-4.1 |
| obtain_token_by_auth_code_flow |
With the auth_response being redirected back, validate it against auth_code_flow, and then obtain tokens. Internally, it implements PKCE to mitigate the auth code interception attack. |
| obtain_token_by_authorization_code |
Get a token via authorization code. a.k.a. Authorization Code Grant. This is typically used by a server-side app (Confidential Client), but it can also be used by a device-side native app (Public Client). See more detail at https://tools.ietf.org/html/rfc6749#section-4.1.3 You are encouraged to use its higher level method obtain_token_by_auth_code_flow instead. |
| obtain_token_by_browser |
A native app can use this method to obtain token via a local browser. Internally, it implements PKCE to mitigate the auth code interception attack. |
| obtain_token_by_device_flow |
Obtain token by a device flow object, with customizable polling effect. |
| obtain_token_by_refresh_token |
This is an overload which will trigger token storage callbacks. |
| obtain_token_by_username_password |
The Resource Owner Password Credentials Grant, used by legacy app. |
| obtain_token_for_client |
Obtain token for this client (rather than for an end user), a.k.a. the Client Credentials Grant, used by Backend Applications. We don't name it obtain_token_by_client_credentials(...) because those credentials are typically already provided in class constructor, not here. You can still explicitly provide an optional client_secret parameter, or you can provide such extra parameters as default_body during the class initialization. |
| parse_auth_response |
Parse the authorization response being redirected back. |
build_auth_request_uri
Generate an authorization uri to be visited by resource owner.
Parameters are the same as another method initiate_auth_code_flow, whose functionality is a superset of this method.
build_auth_request_uri(response_type, redirect_uri=None, scope=None, state=None, **kwargs)
Parameters
- response_type
- redirect_uri
- scope
- state
Returns
The auth uri as a string.
initiate_auth_code_flow
Initiate an auth code flow.
Later when the response reaches your redirect_uri, you can use obtain_token_by_auth_code_flow to complete the authentication/authorization.
This method also provides PKCE protection automatically.
initiate_auth_code_flow(scope=None, redirect_uri=None, state=None, **kwargs)
Parameters
- scope
- list
It is a list of case-sensitive strings. Some ID provider can accept empty string to represent default scope.
- redirect_uri
- str
Optional. If not specified, server will use the pre-registered one.
- state
- str
An opaque value used by the client to maintain state between the request and callback. If absent, this library will automatically generate one internally.
- kwargs
Other parameters, typically defined in OpenID Connect.
Returns
The auth code flow. It is a dict in this form:
{
"auth_uri": "https://...", // Guide user to visit this
"state": "...", // You may choose to verify it by yourself,
// or just let obtain_token_by_auth_code_flow()
// do that for you.
"...": "...", // Everything else are reserved and internal
}
The caller is expected to:
somehow store this content, typically inside the current session,
guide the end user (i.e. resource owner) to visit that auth_uri,
and then relay this dict and subsequent auth response to obtain_token_by_auth_code_flow.
initiate_device_flow
Initiate a device flow.
Returns the data defined in Device Flow specs. https://tools.ietf.org/html/draft-ietf-oauth-device-flow-12#section-3.2
You should then orchestrate the User Interaction as defined in here https://tools.ietf.org/html/draft-ietf-oauth-device-flow-12#section-3.3
And possibly here https://tools.ietf.org/html/draft-ietf-oauth-device-flow-12#section-3.3.1
initiate_device_flow(scope: Optional[list] = None, **kwargs: dict) -> dict
Parameters
- scope
obtain_token_by_assertion
This method implements Assertion Framework for OAuth2 (RFC 7521). See details at https://tools.ietf.org/html/rfc7521#section-4.1
obtain_token_by_assertion()
Parameters
- assertion
The assertion bytes can be a raw SAML2 assertion, or a JWT assertion.
- grant_type
It is typically either the value of GRANT_TYPE_SAML2, or GRANT_TYPE_JWT, the only two profiles defined in RFC 7521.
- scope
Optional. It must be a subset of previously granted scopes.
obtain_token_by_auth_code_flow
With the auth_response being redirected back, validate it against auth_code_flow, and then obtain tokens.
Internally, it implements PKCE to mitigate the auth code interception attack.
obtain_token_by_auth_code_flow(auth_code_flow, auth_response, scope=None, **kwargs)
Parameters
- scope
- <xref:collections.Iterable>[str]
You don't usually need to use scope parameter here. Some Identity Provider allows you to provide a subset of what you specified during initiate_auth_code_flow.
Returns
A dict containing "access_token" and/or "id_token", among others, depends on what scope was used. (See https://tools.ietf.org/html/rfc6749#section-5.1)
A dict containing "error", optionally "error_description", "error_uri". (It is either this or that
Most client-side data error would result in ValueError exception. So the usage pattern could be without any protocol details:
def authorize(): # A controller in a web app try: result = client.obtain_token_by_auth_code_flow( session.get("flow", {}), auth_resp) if "error" in result: return render_template("error.html", result) store_tokens() except ValueError: # Usually caused by CSRF pass # Simply ignore them return redirect(url_for("index"))
obtain_token_by_authorization_code
Get a token via authorization code. a.k.a. Authorization Code Grant.
This is typically used by a server-side app (Confidential Client), but it can also be used by a device-side native app (Public Client). See more detail at https://tools.ietf.org/html/rfc6749#section-4.1.3
You are encouraged to use its higher level method obtain_token_by_auth_code_flow instead.
obtain_token_by_authorization_code(code, redirect_uri=None, scope=None, **kwargs)
Parameters
- code
The authorization code received from authorization server.
- redirect_uri
Required, if the "redirect_uri" parameter was included in the authorization request, and their values MUST be identical.
- scope
It is both unnecessary and harmless to use scope here, per RFC 6749. We suggest to use the same scope already used in auth request uri, so that this library can link the obtained tokens with their scope.
obtain_token_by_browser
A native app can use this method to obtain token via a local browser.
Internally, it implements PKCE to mitigate the auth code interception attack.
obtain_token_by_browser(redirect_uri=None, auth_code_receiver=None, **kwargs)
Parameters
- scope
- <xref:collections.Iterable>[str]
A list of scopes that you would like to obtain token for.
- extra_scope_to_consent
Some IdP allows you to include more scopes for end user to consent. The access token returned by this method will NOT include those scopes, but the refresh token would record those extra consent, so that your future obtain_token_by_refresh_token call would be able to obtain token for those additional scopes, silently.
- redirect_uri
- string
The redirect_uri to be sent via auth request to Identity Provider (IdP),
to indicate where an auth response would come back to.
Such as http://127.0.0.1:0 (default) or http://localhost:1234.
If port 0 is specified, this method will choose a system-allocated port, then the actual redirect_uri will contain that port. To use this behavior, your IdP would need to accept such dynamic port.
Per HTTP convention, if port number is absent, it would mean port 80, although you probably want to specify port 0 in this context.
- browser_name
- str
If you did
webbrowser.register("xyz", None, BackgroundBrowser("/path/to/browser"))
beforehand, you can pass in the name "xyz" to use that browser.
The default value None means using default browser,
which is customizable by env var $BROWSER.
Returns
Same as obtain_token_by_auth_code_flow
obtain_token_by_device_flow
Obtain token by a device flow object, with customizable polling effect.
obtain_token_by_device_flow()
Parameters
- flow
- dict
An object previously generated by initiate_device_flow(...). Its content WILL BE CHANGED by this method during each run. We share this object with you, so that you could implement your own loop, should you choose to do so.
- exit_condition
- <xref:Callable>
This method implements a loop to provide polling effect. The loop's exit condition is calculated by this callback.
The default callback makes the loop run until the flow expires. Therefore, one of the ways to exit the polling early, is to change the flow["expires_at"] to a small number such as 0.
In case you are doing async programming, you may want to completely turn off the loop. You can do so by using a callback as:
exit_condition = lambda flow: True
to make the loop run only once, i.e. no polling, hence non-block.
obtain_token_by_refresh_token
This is an overload which will trigger token storage callbacks.
obtain_token_by_refresh_token()
Parameters
- token_item
A refresh token (RT) item, in flexible format. It can be a string, or a whatever data structure containing RT string and its metadata, in such case the rt_getter callable must be able to extract the RT string out from the token item data structure.
Either way, this token_item will be passed into other callbacks as-is.
- scope
If omitted, is treated as equal to the scope originally granted by the resource owner, according to https://tools.ietf.org/html/rfc6749#section-6
- rt_getter
A callable to translate the token_item to a raw RT string
- on_removing_rt
If absent, fall back to the one defined in initialization
- on_updating_rt
Default to None, it will fall back to the one defined in initialization. This is the most common case.
As a special case, you can pass in a False, then this function will NOT trigger on_updating_rt() for RT UPDATE, instead it will allow the RT to be added by on_obtaining_tokens(). This behavior is useful when you are migrating RTs from elsewhere into a token storage managed by this library.
obtain_token_by_username_password
The Resource Owner Password Credentials Grant, used by legacy app.
obtain_token_by_username_password(username, password, scope=None, **kwargs)
Parameters
- username
- password
- scope
obtain_token_for_client
Obtain token for this client (rather than for an end user), a.k.a. the Client Credentials Grant, used by Backend Applications.
We don't name it obtain_token_by_client_credentials(...) because those credentials are typically already provided in class constructor, not here. You can still explicitly provide an optional client_secret parameter, or you can provide such extra parameters as default_body during the class initialization.
obtain_token_for_client(scope=None, **kwargs)
Parameters
- scope
parse_auth_response
Parse the authorization response being redirected back.
static parse_auth_response(params, state=None)
Parameters
- params
A string or dict of the query string
- state
REQUIRED if the state parameter was present in the client authorization request. This function will compare it with response.
Attributes
DEVICE_FLOW
DEVICE_FLOW = {'DEVICE_CODE': 'device_code', 'GRANT_TYPE': 'urn:ietf:params:oauth:grant-type:device_code'}
DEVICE_FLOW_RETRIABLE_ERRORS
DEVICE_FLOW_RETRIABLE_ERRORS = ('authorization_pending', 'slow_down')
GRANT_TYPE_JWT
GRANT_TYPE_JWT = 'urn:ietf:params:oauth:grant-type:jwt-bearer'
GRANT_TYPE_SAML2
GRANT_TYPE_SAML2 = 'urn:ietf:params:oauth:grant-type:saml2-bearer'
grant_assertion_encoders
grant_assertion_encoders = {'urn:ietf:params:oauth:grant-type:saml2-bearer': <function BaseClient.encode_saml_assertion>}
Feedback
Submit and view feedback for