open-webui: do not login when not belonging to user or admin group

This commit is contained in:
ibizaman 2025-10-06 23:39:09 +02:00 committed by Pierre Penninckx
parent 81dc4f280d
commit a536ee141e
3 changed files with 87 additions and 15 deletions

View file

@ -4,6 +4,9 @@ let
contracts = pkgs.callPackage ../contracts {}; contracts = pkgs.callPackage ../contracts {};
shblib = pkgs.callPackage ../../lib {}; shblib = pkgs.callPackage ../../lib {};
roleClaim = "openwebui_groups";
oauthScopes = [ "openid" "email" "profile" "groups" "${roleClaim}" ];
in in
{ {
options.shb.open-webui = { options.shb.open-webui = {
@ -191,21 +194,11 @@ in
${cfg.ldap.adminGroup} = {}; ${cfg.ldap.adminGroup} = {};
}; };
shb.authelia.oidcClients = [
{
client_id = cfg.sso.clientID;
client_secret.source = cfg.sso.sharedSecretForAuthelia.result.path;
scopes = [ "openid" "email" "profile" ];
authorization_policy = cfg.sso.authorization_policy;
redirect_uris = [
"https://${cfg.subdomain}.${cfg.domain}/oauth/oidc/callback"
];
}
];
services.open-webui = { services.open-webui = {
package = pkgs.open-webui.overrideAttrs (finalAttrs: { package = pkgs.open-webui.overrideAttrs (finalAttrs: {
patches = [ patches = [
../../patches/0001-selfhostblocks-never-onboard.patch ../../patches/0001-selfhostblocks-never-onboard.patch
../../patches/0002-selfhostblocks-do-not-allow-unauthorized-roles.patch
]; ];
}); });
environment = { environment = {
@ -217,13 +210,43 @@ in
OAUTH_CLIENT_ID = cfg.sso.clientID; OAUTH_CLIENT_ID = cfg.sso.clientID;
OPENID_PROVIDER_URL = "${cfg.sso.authEndpoint}/.well-known/openid-configuration"; OPENID_PROVIDER_URL = "${cfg.sso.authEndpoint}/.well-known/openid-configuration";
OAUTH_PROVIDER_NAME = "Single Sign-On"; OAUTH_PROVIDER_NAME = "Single Sign-On";
OAUTH_SCOPES = "openid email profile"; OAUTH_USERNAME_CLAIM = "preferred_username";
OAUTH_ALLOWED_ROLES = cfg.ldap.userGroup;
OAUTH_ADMIN_ROLES = cfg.ldap.adminGroup;
ENABLE_OAUTH_ROLE_MANAGEMENT = "True"; ENABLE_OAUTH_ROLE_MANAGEMENT = "True";
OAUTH_ALLOWED_ROLES = "user,admin";
OAUTH_ADMIN_ROLES = "admin";
OAUTH_ROLES_CLAIM = roleClaim;
OAUTH_SCOPES = lib.concatStringsSep " " oauthScopes;
}; };
}; };
shb.authelia.extraDefinitions = {
user_attributes.${roleClaim}.expression =
''"${cfg.ldap.adminGroup}" in groups ? ["admin"] : ("${cfg.ldap.userGroup}" in groups ? ["user"] : [""])'';
};
shb.authelia.extraOidcClaimsPolicies.${roleClaim} = {
custom_claims = {
"${roleClaim}" = {};
};
};
shb.authelia.extraOidcScopes."${roleClaim}" = {
claims = [ "${roleClaim}" ];
};
shb.authelia.oidcClients = [
{
client_id = cfg.sso.clientID;
client_name = "Open WebUI";
client_secret.source = cfg.sso.sharedSecretForAuthelia.result.path;
claims_policy = "${roleClaim}";
public = false;
authorization_policy = cfg.sso.authorization_policy;
redirect_uris = [
"https://${cfg.subdomain}.${cfg.domain}/oauth/oidc/callback"
];
scopes = oauthScopes;
}
];
systemd.services.open-webui.serviceConfig.EnvironmentFile = "/run/open-webui/secrets.env"; systemd.services.open-webui.serviceConfig.EnvironmentFile = "/run/open-webui/secrets.env";
systemd.tmpfiles.rules = [ systemd.tmpfiles.rules = [
"d '/run/open-webui' 0750 root root - -" "d '/run/open-webui' 0750 root root - -"

View file

@ -11,12 +11,13 @@ This service sets up [Open WebUI][] which provides a frontend to various LLMs.
## Features {#services-open-webui-features} ## Features {#services-open-webui-features}
- Telemetry disabled. - Telemetry disabled.
- Skip onboarding. - Skip onboarding through custom patch.
- Declarative [LDAP](#services-open-webui-options-shb.open-webui.ldap) Configuration. - Declarative [LDAP](#services-open-webui-options-shb.open-webui.ldap) Configuration.
Needed LDAP groups are created automatically. Needed LDAP groups are created automatically.
- Declarative [SSO](#services-open-webui-options-shb.open-webui.sso) Configuration. - Declarative [SSO](#services-open-webui-options-shb.open-webui.sso) Configuration.
When SSO is enabled, login with user and password is disabled. When SSO is enabled, login with user and password is disabled.
Registration is enabled through SSO. Registration is enabled through SSO.
Correct error message for unauthorized user through custom patch.
- Access through [subdomain](#services-open-webui-options-shb.open-webui.subdomain) using reverse proxy. - Access through [subdomain](#services-open-webui-options-shb.open-webui.subdomain) using reverse proxy.
- Access through [HTTPS](#services-open-webui-options-shb.open-webui.ssl) using reverse proxy. - Access through [HTTPS](#services-open-webui-options-shb.open-webui.ssl) using reverse proxy.
- [Backup](#services-open-webui-options-shb.open-webui.sso) through the [backup block](./blocks-backup.html). - [Backup](#services-open-webui-options-shb.open-webui.sso) through the [backup block](./blocks-backup.html).

View file

@ -0,0 +1,48 @@
From fed4cfab1f66e6a2a46dbdd20ad52aee664f06b1 Mon Sep 17 00:00:00 2001
From: ibizaman <ibizaman@tiserbox.com>
Date: Thu, 9 Oct 2025 01:37:43 +0200
Subject: [PATCH] selfhostblocks: do not allow unauthorized roles
---
backend/open_webui/constants.py | 2 +-
backend/open_webui/utils/oauth.py | 5 +++--
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/backend/open_webui/constants.py b/backend/open_webui/constants.py
index 59ee6aaac..5a42f1805 100644
--- a/backend/open_webui/constants.py
+++ b/backend/open_webui/constants.py
@@ -51,7 +51,7 @@ class ERROR_MESSAGES(str, Enum):
EXISTING_USERS = "You can't turn off authentication because there are existing users. If you want to disable WEBUI_AUTH, make sure your web interface doesn't have any existing users and is a fresh installation."
- UNAUTHORIZED = "401 Unauthorized"
+ UNAUTHORIZED = "Unauthorized"
ACCESS_PROHIBITED = "You do not have permission to access this resource. Please contact your administrator for assistance."
ACTION_PROHIBITED = (
"The requested action has been restricted as a security measure."
diff --git a/backend/open_webui/utils/oauth.py b/backend/open_webui/utils/oauth.py
index 9090c38ce..3c68dead4 100644
--- a/backend/open_webui/utils/oauth.py
+++ b/backend/open_webui/utils/oauth.py
@@ -336,8 +336,7 @@ class OAuthManager:
oauth_allowed_roles = auth_manager_config.OAUTH_ALLOWED_ROLES
oauth_admin_roles = auth_manager_config.OAUTH_ADMIN_ROLES
oauth_roles = []
- # Default/fallback role if no matching roles are found
- role = auth_manager_config.DEFAULT_USER_ROLE
+ role = None
# Next block extracts the roles from the user data, accepting nested claims of any depth
if oauth_claim and oauth_allowed_roles and oauth_admin_roles:
@@ -373,6 +372,8 @@ class OAuthManager:
log.debug("Assigned user the admin role")
role = "admin"
break
+ if role is None:
+ raise HTTPException(403, detail=ERROR_MESSAGES.UNAUTHORIZED)
else:
if not user:
# If role management is disabled, use the default role for new users
--
2.50.1