enh: option to disable api auth

This commit is contained in:
Timothy Jaeryang Baek 2024-11-19 12:17:23 -08:00
parent 979e6e5a79
commit 7a585fbaf3
8 changed files with 34 additions and 30 deletions

View File

@ -35,6 +35,7 @@ from open_webui.config import (
ENABLE_LOGIN_FORM, ENABLE_LOGIN_FORM,
ENABLE_MESSAGE_RATING, ENABLE_MESSAGE_RATING,
ENABLE_SIGNUP, ENABLE_SIGNUP,
ENABLE_API_KEY,
ENABLE_EVALUATION_ARENA_MODELS, ENABLE_EVALUATION_ARENA_MODELS,
EVALUATION_ARENA_MODELS, EVALUATION_ARENA_MODELS,
DEFAULT_ARENA_MODEL, DEFAULT_ARENA_MODEL,
@ -98,6 +99,8 @@ app.state.config = AppConfig()
app.state.config.ENABLE_SIGNUP = ENABLE_SIGNUP app.state.config.ENABLE_SIGNUP = ENABLE_SIGNUP
app.state.config.ENABLE_LOGIN_FORM = ENABLE_LOGIN_FORM app.state.config.ENABLE_LOGIN_FORM = ENABLE_LOGIN_FORM
app.state.config.ENABLE_API_KEY = ENABLE_API_KEY
app.state.config.JWT_EXPIRES_IN = JWT_EXPIRES_IN app.state.config.JWT_EXPIRES_IN = JWT_EXPIRES_IN
app.state.AUTH_TRUSTED_EMAIL_HEADER = WEBUI_AUTH_TRUSTED_EMAIL_HEADER app.state.AUTH_TRUSTED_EMAIL_HEADER = WEBUI_AUTH_TRUSTED_EMAIL_HEADER
app.state.AUTH_TRUSTED_NAME_HEADER = WEBUI_AUTH_TRUSTED_NAME_HEADER app.state.AUTH_TRUSTED_NAME_HEADER = WEBUI_AUTH_TRUSTED_NAME_HEADER

View File

@ -18,7 +18,7 @@ from open_webui.apps.webui.models.auths import (
UserResponse, UserResponse,
) )
from open_webui.apps.webui.models.users import Users from open_webui.apps.webui.models.users import Users
from open_webui.config import ENABLE_API_KEY_AUTH
from open_webui.constants import ERROR_MESSAGES, WEBHOOK_MESSAGES from open_webui.constants import ERROR_MESSAGES, WEBHOOK_MESSAGES
from open_webui.env import ( from open_webui.env import (
WEBUI_AUTH, WEBUI_AUTH,
@ -581,6 +581,7 @@ async def get_admin_config(request: Request, user=Depends(get_admin_user)):
return { return {
"SHOW_ADMIN_DETAILS": request.app.state.config.SHOW_ADMIN_DETAILS, "SHOW_ADMIN_DETAILS": request.app.state.config.SHOW_ADMIN_DETAILS,
"ENABLE_SIGNUP": request.app.state.config.ENABLE_SIGNUP, "ENABLE_SIGNUP": request.app.state.config.ENABLE_SIGNUP,
"ENABLE_API_KEY": request.app.state.config.ENABLE_API_KEY,
"DEFAULT_USER_ROLE": request.app.state.config.DEFAULT_USER_ROLE, "DEFAULT_USER_ROLE": request.app.state.config.DEFAULT_USER_ROLE,
"JWT_EXPIRES_IN": request.app.state.config.JWT_EXPIRES_IN, "JWT_EXPIRES_IN": request.app.state.config.JWT_EXPIRES_IN,
"ENABLE_COMMUNITY_SHARING": request.app.state.config.ENABLE_COMMUNITY_SHARING, "ENABLE_COMMUNITY_SHARING": request.app.state.config.ENABLE_COMMUNITY_SHARING,
@ -591,6 +592,7 @@ async def get_admin_config(request: Request, user=Depends(get_admin_user)):
class AdminConfig(BaseModel): class AdminConfig(BaseModel):
SHOW_ADMIN_DETAILS: bool SHOW_ADMIN_DETAILS: bool
ENABLE_SIGNUP: bool ENABLE_SIGNUP: bool
ENABLE_API_KEY: bool
DEFAULT_USER_ROLE: str DEFAULT_USER_ROLE: str
JWT_EXPIRES_IN: str JWT_EXPIRES_IN: str
ENABLE_COMMUNITY_SHARING: bool ENABLE_COMMUNITY_SHARING: bool
@ -603,6 +605,7 @@ async def update_admin_config(
): ):
request.app.state.config.SHOW_ADMIN_DETAILS = form_data.SHOW_ADMIN_DETAILS request.app.state.config.SHOW_ADMIN_DETAILS = form_data.SHOW_ADMIN_DETAILS
request.app.state.config.ENABLE_SIGNUP = form_data.ENABLE_SIGNUP request.app.state.config.ENABLE_SIGNUP = form_data.ENABLE_SIGNUP
request.app.state.config.ENABLE_API_KEY = form_data.ENABLE_API_KEY
if form_data.DEFAULT_USER_ROLE in ["pending", "user", "admin"]: if form_data.DEFAULT_USER_ROLE in ["pending", "user", "admin"]:
request.app.state.config.DEFAULT_USER_ROLE = form_data.DEFAULT_USER_ROLE request.app.state.config.DEFAULT_USER_ROLE = form_data.DEFAULT_USER_ROLE
@ -621,6 +624,7 @@ async def update_admin_config(
return { return {
"SHOW_ADMIN_DETAILS": request.app.state.config.SHOW_ADMIN_DETAILS, "SHOW_ADMIN_DETAILS": request.app.state.config.SHOW_ADMIN_DETAILS,
"ENABLE_SIGNUP": request.app.state.config.ENABLE_SIGNUP, "ENABLE_SIGNUP": request.app.state.config.ENABLE_SIGNUP,
"ENABLE_API_KEY": request.app.state.config.ENABLE_API_KEY,
"DEFAULT_USER_ROLE": request.app.state.config.DEFAULT_USER_ROLE, "DEFAULT_USER_ROLE": request.app.state.config.DEFAULT_USER_ROLE,
"JWT_EXPIRES_IN": request.app.state.config.JWT_EXPIRES_IN, "JWT_EXPIRES_IN": request.app.state.config.JWT_EXPIRES_IN,
"ENABLE_COMMUNITY_SHARING": request.app.state.config.ENABLE_COMMUNITY_SHARING, "ENABLE_COMMUNITY_SHARING": request.app.state.config.ENABLE_COMMUNITY_SHARING,
@ -734,14 +738,16 @@ async def update_ldap_config(
# create api key # create api key
@router.post("/api_key", response_model=ApiKey) @router.post("/api_key", response_model=ApiKey)
async def create_api_key_(user=Depends(get_current_user)): async def create_api_key(request: Request, user=Depends(get_current_user)):
if not ENABLE_API_KEY_AUTH: if not request.app.config.state.ENABLE_API_KEY:
raise HTTPException( raise HTTPException(
status.HTTP_403_FORBIDDEN, detail=ERROR_MESSAGES.API_KEY_CREATION_NOT_ALLOWED status.HTTP_403_FORBIDDEN,
detail=ERROR_MESSAGES.API_KEY_CREATION_NOT_ALLOWED,
) )
api_key = create_api_key() api_key = create_api_key()
success = Users.update_user_api_key_by_id(user.id, api_key) success = Users.update_user_api_key_by_id(user.id, api_key)
if success: if success:
return { return {
"api_key": api_key, "api_key": api_key,

View File

@ -265,10 +265,13 @@ class AppConfig:
# WEBUI_AUTH (Required for security) # WEBUI_AUTH (Required for security)
#################################### ####################################
ENABLE_API_KEY_AUTH = ( ENABLE_API_KEY = PersistentConfig(
os.environ.get("ENABLE_API_KEY_AUTH", "True").lower() == "true" "ENABLE_API_KEY",
"auth.api_key.enable",
os.environ.get("ENABLE_API_KEY", "True").lower() == "true",
) )
JWT_EXPIRES_IN = PersistentConfig( JWT_EXPIRES_IN = PersistentConfig(
"JWT_EXPIRES_IN", "auth.jwt_expiry", os.environ.get("JWT_EXPIRES_IN", "-1") "JWT_EXPIRES_IN", "auth.jwt_expiry", os.environ.get("JWT_EXPIRES_IN", "-1")
) )

View File

@ -74,7 +74,6 @@ from open_webui.config import (
ENABLE_ADMIN_EXPORT, ENABLE_ADMIN_EXPORT,
ENABLE_OLLAMA_API, ENABLE_OLLAMA_API,
ENABLE_OPENAI_API, ENABLE_OPENAI_API,
ENABLE_API_KEY_AUTH,
ENABLE_TAGS_GENERATION, ENABLE_TAGS_GENERATION,
ENV, ENV,
FRONTEND_BUILD_DIR, FRONTEND_BUILD_DIR,
@ -941,6 +940,7 @@ async def commit_session_after_request(request: Request, call_next):
@app.middleware("http") @app.middleware("http")
async def check_url(request: Request, call_next): async def check_url(request: Request, call_next):
start_time = int(time.time()) start_time = int(time.time())
request.state.enable_api_key = webui_app.state.config.ENABLE_API_KEY
response = await call_next(request) response = await call_next(request)
process_time = int(time.time()) - start_time process_time = int(time.time()) - start_time
response.headers["X-Process-Time"] = str(process_time) response.headers["X-Process-Time"] = str(process_time)
@ -2428,7 +2428,7 @@ async def get_app_config(request: Request):
"auth": WEBUI_AUTH, "auth": WEBUI_AUTH,
"auth_trusted_header": bool(webui_app.state.AUTH_TRUSTED_EMAIL_HEADER), "auth_trusted_header": bool(webui_app.state.AUTH_TRUSTED_EMAIL_HEADER),
"enable_ldap": webui_app.state.config.ENABLE_LDAP, "enable_ldap": webui_app.state.config.ENABLE_LDAP,
"enable_api_key_auth": ENABLE_API_KEY_AUTH, "enable_api_key": webui_app.state.config.ENABLE_API_KEY,
"enable_signup": webui_app.state.config.ENABLE_SIGNUP, "enable_signup": webui_app.state.config.ENABLE_SIGNUP,
"enable_login_form": webui_app.state.config.ENABLE_LOGIN_FORM, "enable_login_form": webui_app.state.config.ENABLE_LOGIN_FORM,
**( **(

View File

@ -73,15 +73,10 @@ def get_http_authorization_cred(auth_header: str):
except Exception: except Exception:
raise ValueError(ERROR_MESSAGES.INVALID_TOKEN) raise ValueError(ERROR_MESSAGES.INVALID_TOKEN)
def get_api_key_auth_config():
from open_webui.config import ENABLE_API_KEY_AUTH
return ENABLE_API_KEY_AUTH
def get_current_user( def get_current_user(
request: Request, request: Request,
auth_token: HTTPAuthorizationCredentials = Depends(bearer_security), auth_token: HTTPAuthorizationCredentials = Depends(bearer_security),
api_key_auth_enabled: bool = Depends(get_api_key_auth_config)
): ):
token = None token = None
@ -96,14 +91,13 @@ def get_current_user(
# auth by api key # auth by api key
if token.startswith("sk-"): if token.startswith("sk-"):
if not api_key_auth_enabled: if not request.state.enable_api_key:
raise HTTPException( raise HTTPException(
status.HTTP_403_FORBIDDEN, detail=ERROR_MESSAGES.API_KEY_NOT_ALLOWED status.HTTP_403_FORBIDDEN, detail=ERROR_MESSAGES.API_KEY_NOT_ALLOWED
) )
return get_current_user_by_api_key(token) return get_current_user_by_api_key(token)
# auth by jwt token # auth by jwt token
try: try:
data = decode_token(token) data = decode_token(token)
except Exception as e: except Exception as e:

View File

@ -112,6 +112,12 @@
</div> </div>
</div> </div>
<div class=" flex w-full justify-between pr-2">
<div class=" self-center text-xs font-medium">{$i18n.t('Enable API Key Auth')}</div>
<Switch bind:state={adminConfig.ENABLE_API_KEY} />
</div>
<hr class=" border-gray-50 dark:border-gray-850 my-2" /> <hr class=" border-gray-50 dark:border-gray-850 my-2" />
<div class="my-3 flex w-full items-center justify-between pr-2"> <div class="my-3 flex w-full items-center justify-between pr-2">

View File

@ -26,9 +26,6 @@
let APIKey = ''; let APIKey = '';
let APIKeyCopied = false; let APIKeyCopied = false;
$: enableApiKeyAuth = $config?.features.enable_api_key_auth ?? true;
let profileImageInputElement: HTMLInputElement; let profileImageInputElement: HTMLInputElement;
const submitHandler = async () => { const submitHandler = async () => {
@ -303,16 +300,11 @@
</button> </button>
</div> </div>
</div> </div>
<div class="justify-between w-full"> {#if $config?.features?.enable_api_key ?? true}
<div class="flex justify-between w-full"> <div class="justify-between w-full">
<div class="self-center text-xs font-medium">{$i18n.t('API Key')}</div> <div class="flex justify-between w-full">
</div> <div class="self-center text-xs font-medium">{$i18n.t('API Key')}</div>
{#if !enableApiKeyAuth}
<div class="mt-2 p-2 bg-yellow-500/20 text-yellow-700 dark:text-yellow-200 rounded-lg">
{$i18n.t('Private API keys are disabled in this environment')}
</div> </div>
{:else}
<div class="flex mt-2"> <div class="flex mt-2">
{#if APIKey} {#if APIKey}
<SensitiveInput value={APIKey} readOnly={true} /> <SensitiveInput value={APIKey} readOnly={true} />
@ -397,8 +389,8 @@
> >
{/if} {/if}
</div> </div>
{/if} </div>
</div> {/if}
</div> </div>
{/if} {/if}
</div> </div>

View File

@ -172,7 +172,7 @@ type Config = {
features: { features: {
auth: boolean; auth: boolean;
auth_trusted_header: boolean; auth_trusted_header: boolean;
enable_api_key_auth: boolean; enable_api_key: boolean;
enable_signup: boolean; enable_signup: boolean;
enable_login_form: boolean; enable_login_form: boolean;
enable_web_search?: boolean; enable_web_search?: boolean;