Implemented OIDC confidential client type support. Updated README.md. Added missing environment variables to docker-compose.yml

This commit is contained in:
Glenn de Haan
2024-08-26 19:32:31 +02:00
parent 36468b4588
commit cb6ed67c9c
3 changed files with 71 additions and 6 deletions

View File

@@ -64,6 +64,10 @@ services:
AUTH_OIDC_APP_BASE_URL: ''
# OIDC client id provided by oauth provider
AUTH_OIDC_CLIENT_ID: ''
# OIDC client type, public/confidential
AUTH_OIDC_CLIENT_TYPE: 'public'
# OIDC client secret provided by oauth provider (Only required when using confidential client type)
AUTH_OIDC_CLIENT_SECRET: ''
# Disables the login/authentication for the portal and API
AUTH_DISABLE: 'false'
# Voucher Types, format: expiration in minutes (required),single-use or multi-use vouchers value - '0' is for multi-use - '1' is for single-use (optional),upload speed limit in kbps (optional),download speed limit in kbps (optional),data transfer limit in MB (optional)
@@ -313,7 +317,7 @@ Once the SMTP environment variables are configured, the email feature will be av
## OpenID Connect (OIDC) Authentication
The UniFi Voucher Site allows seamless integration with OpenID Connect (OIDC), enabling users to authenticate through their preferred identity provider (IdP). The setup is straightforward, requiring configuration through environment variables to align with your existing OIDC provider.
The UniFi Voucher Site allows seamless integration with OpenID Connect (OIDC), enabling users to authenticate through their preferred identity provider (IdP). With support for both Public and Confidential client types. Configuration is easy using environment variables to align with your existing OIDC provider.
### Configuration
@@ -328,13 +332,63 @@ To enable OIDC authentication, set the following environment variables in your a
- **`AUTH_OIDC_CLIENT_ID`**:
The client ID registered with your OIDC provider. This value is specific to the OIDC client created for the UniFi Voucher Site.
- **`AUTH_OIDC_CLIENT_TYPE`**:
Specify the type of OIDC client:
- **`public`**: Uses the Implicit flow (default).
- **`confidential`**: Uses the Authorization Code flow with client secret.
- **`AUTH_OIDC_CLIENT_SECRET`** (required if using the Confidential client type):
The client secret associated with your OIDC provider, necessary when using the Authorization Code flow.
> Please note that **enabling OIDC support will automatically disable the built-in login system**. Once OIDC is activated, all user authentication will be handled through your configured identity provider, and the local login mechanism will no longer be available.
### OIDC Client Configuration
When configuring your OIDC client, ensure that the following settings are enabled:
When configuring your OIDC client, ensure the following settings are enabled based on your chosen client type:
- **Implicit Flow Support**: The OIDC client **must** support the Implicit flow. This is essential as the UniFi Voucher Site relies on this flow for authentication.
- **Public Client (Implicit Flow)**: The OIDC client **must** support the Implicit flow. Be sure to enable both the ID token and access token retrieval.
- **Confidential Client (Authorization Code Flow)**: The client secret is required for secure token exchanges.
### Determine Supported Client Types
To identify which client types your OpenID Connect (OIDC) provider supports (Public or Confidential), you can check the `.well-known/openid-configuration` endpoint. This endpoint contains metadata about the OIDC provider, including the supported flows and grant types.
#### Steps to Check Supported Client Types
1. **Access the `.well-known/openid-configuration` URL:**
The URL is typically structured like this:
```text
https://auth.example.com/.well-known/openid-configuration
```
2. **Look for the `grant_types_supported` Field:**
In the returned JSON, the `grant_types_supported` field will indicate the flows your provider supports:
- **For Public Clients (Implicit Flow):** Look for `implicit`.
- **For Confidential Clients (Authorization Code Flow):** Look for `authorization_code`.
Example snippet:
```json
{
"grant_types_supported": [
"authorization_code",
"implicit",
"refresh_token",
"client_credentials"
]
}
```
3. **Check the `response_types_supported` Field:**
This field also provides details on supported client types:
- **Implicit Flow:** Should include values like `id_token` or `id_token token`.
- **Authorization Code Flow:** Should include `code`.
4. **Verify Client Authentication Methods:**
For confidential clients, confirm that the `token_endpoint_auth_methods_supported` field lists options like `client_secret_post` or `client_secret_basic`, which indicate that the provider supports client secret authentication.
## Screenshots

View File

@@ -12,6 +12,11 @@ services:
UNIFI_SITE_ID: 'default'
AUTH_PASSWORD: '0000'
AUTH_TOKEN: '00000000-0000-0000-0000-000000000000'
AUTH_OIDC_ISSUER_BASE_URL: ''
AUTH_OIDC_APP_BASE_URL: ''
AUTH_OIDC_CLIENT_ID: ''
AUTH_OIDC_CLIENT_TYPE: 'public'
AUTH_OIDC_CLIENT_SECRET: ''
AUTH_DISABLE: 'false'
VOUCHER_TYPES: '480,1,,,;'
VOUCHER_CUSTOM: 'true'

View File

@@ -12,15 +12,21 @@ const log = require('./log');
/**
* OIDC Settings
*
* @type {{baseURL: string, idpLogout: boolean, authRequired: boolean, clientID: string, issuerBaseURL: string, secret: string}}
* @type {{baseURL: string, idpLogout: boolean, authRequired: boolean, clientID: string, issuerBaseURL: string, clientSecret: string, secret: string, authorizationParams: {scope: string, response_type: (string), response_mode: (string)}}}
*/
const settings = {
issuerBaseURL: process.env.AUTH_OIDC_ISSUER_BASE_URL,
baseURL: process.env.AUTH_OIDC_APP_BASE_URL,
clientID: process.env.AUTH_OIDC_CLIENT_ID,
clientSecret: process.env.AUTH_OIDC_CLIENT_SECRET,
secret: '',
idpLogout: true,
authRequired: false
authRequired: false,
authorizationParams: {
response_type: (process.env.AUTH_OIDC_CLIENT_TYPE === 'confidential') ? 'code' : 'id_token',
response_mode: (process.env.AUTH_OIDC_CLIENT_TYPE === 'confidential') ? 'query' : 'form_post',
scope: 'openid profile email'
}
};
/**
@@ -36,6 +42,6 @@ module.exports = {
settings.secret = crypto.randomBytes(20).toString('hex');
log.info(`[OIDC] Set secret: ${settings.secret}`);
app.use(oidc.auth(settings));
log.info(`[OIDC] Issuer: ${settings.issuerBaseURL}, Client: ${settings.clientID}`);
log.info(`[OIDC] Issuer: ${settings.issuerBaseURL}, Client: ${settings.clientID}, Type: ${process.env.AUTH_OIDC_CLIENT_TYPE || 'public'}`);
}
};