Configure OIDC Clients
In addition to traditional username and password authentication, HIdP supports authentication using OpenID Connect (OIDC).
HIdP has built-in support for both Google and Microsoft as OIDC providers, and can be extended to support others.
Quick Start
To enable OIDC authentication, you need to configure the OIDC clients in your Django settings.
from hidp import config as hidp_config
from hidp.federated.providers.google import GoogleOIDCClient
from hidp.federated.providers.microsoft import MicrosoftOIDCClient
hidp_config.configure_oidc_clients(
GoogleOIDCClient(client_id="your-client-id", client_secret="****"),
MicrosoftOIDCClient(client_id="your-client-id"),
)
Important
Never expose a client secret in the source code or client-side code. Use environment variables or a secret management tool to store the client secret.
Note
It is strongly recommended to run the refresh_oidc_clients_jwks
management command
after each deploy and at least once a day to ensure the JWKs are up to date.
See the documentation on refreshing OIDC clients JWKs for more information.
Obtaining Client Credentials
To use Google and/or Microsoft as an OIDC provider, you’ll need to create a “project” in their respective online portals and configure the client with the correct credentials in HIdP.
Google
Follow the instructions from Google on how to set up OpenID Connect on the Google Identity Platform.
Quick start:
Create a new project in the Google Cloud Console, and make sure to select it as the active project. Skip this step if you already have a project.
Configure the OAuth consent screen. This is required for the OAuth 2.0 flow. It is not possible to obtain OAuth 2.0 credentials without configuring this.
Note
Uploading a logo will require verification of the application. Avoid uploading a logo if you are creating a test application.
Note
App domains and authorized domains are not required for testing. They can be left empty.
-
Select “Web application” as the application type.
Configure the authorized redirect URI:
https://<domain>/login/oidc/callback/google/
Note: The redirect URI must be a valid public URL or localhost. For development use either localhost or a hosts file entry to map a public domain to a local development server.
Tip
Use local.<production-domain>
to avoid squatting on a real domain.
Save the client ID and client secret, they will be required for the OpenID Connect client configuration.
In your Django settings, add the following:
from hidp import config as hidp_config
from hidp.federated.providers.google import GoogleOIDCClient
hidp_config.configure_oidc_clients(
GoogleOIDCClient(client_id="your-client-id", client_secret="****"),
)
Important
Never expose the client secret in the source code or client-side code. Use environment variables or a secret management tool to store the client secret.
Microsoft
Follow the instructions from Microsoft on how to set up OpenID Connect on the Microsoft Identity Platform.
Quick start:
Register a new application in the Entra portal
Set the application type to “Single Page Application”. This enables the Code Flow with PKCE, and avoids the need for a client secret.
Pick the broadest account type possible (organization, personal, etc.)
Set the redirect URI to: https://
/login/oidc/callback/microsoft/ Private domains (e.g. *.local, *.test) are allowed.
In your Django settings, add the following:
from hidp import config as hidp_config
from hidp.federated.providers.microsoft import MicrosoftOIDCClient
hidp_config.configure_oidc_clients(
MicrosoftOIDCClient(client_id="your-client-id"),
)
Note
Creating a client that is limited to a specific tenant (Active Directory, or similar)
has not been tested and might require some customisation of the
provided MicrosoftOIDCClient
.
Adding support for other OIDC Providers
To support other OIDC providers, you can implement a custom client based on
the OIDCClient
class configuring the required attributes.
Important
HIdP only supports the Authorization Code flow. Other flows, like the Implicit flow, are considered insecure and will not work.
- class hidp.federated.providers.base.OIDCClient(*, client_id, client_secret=None, callback_base_url=None)
Base class for OpenID Connect clients.
Needs to be overridden and configured, according to the provider’s specifications.
- provider_key
Provider key, used to identify the provider in the application.
This should be unique, descriptive, url-safe and, preferably, lowercase.
- Type:
str
- name
Provider name, used for display purposes. Will default to the capitalized provider key if not set.
- Type:
str
, optional
- issuer
OpenID Connect issuer URL.
- Type:
str
- authorization_endpoint
OpenID Connect authorization endpoint URL.
- Type:
str
- token_endpoint
OpenID Connect token endpoint URL.
- Type:
str
- userinfo_endpoint
OpenID Connect userinfo endpoint URL.
- Type:
str
- jwks_uri
OpenID Connect JWKS URI.
- Type:
str
- has_pkce_support
Whether the provider supports PKCE (Proof Key for Code Exchange).
Note: Only set to True if the provider supports S256 as the code challenge method.
- Type:
boolean
- client_id
Provider assigned client ID.
- Type:
str
- client_secret
Provider assigned client secret, if required for token exchange.
- Type:
str
, optional
- callback_base_url
Alternative base URL to use instead of the one of the request when constructing the callback URL.
- Type:
str
, optional
- get_issuer(*, claims)
Return the expected value of the ‘iss’ claim in the ID token.
Only override this method if absolutely necessary.
- Parameters:
claims (
dict
) – The claims from the ID token.- Returns:
The expected issuer URL based on the claims.
- Return type:
str
- static normalize_userinfo(*, userinfo)
Normalize the data from the userinfo endpoint to the standard format.
This method should only be overridden if absolutely necessary.
- Parameters:
userinfo (
dict
) – The raw data from the userinfo endpoint.- Returns:
The normalized userinfo data.
- Return type:
dict
Tip
OpenID Connect configuration can usually be extracted from the provider’s discovery document, commonly found at: https://<provider>/.well-known/openid-configuration
Make sure to register your custom client:
from hidp import config as hidp_config
hidp_config.configure_oidc_clients(
MyCustomOIDCClient(client_id="your-client-id"),
)