keycloak/keycloak

Custom Required Actions cannot be removed via PUT /admin/realms/{realm}/users/{id}

已关闭

#48,144 创建于 2026年4月16日

 (2 条评论) (2 个反应) (0 位负责人)Java (8,346 个派生)batch import
area/admin/apihelp wantedkind/bugpriority/normalstatus/auto-bumpstatus/auto-expireteam/core-protocolsteam/core-shared

仓库指标

星标
 (34,398 个星标)
PR 合并指标
 (平均合并 6天 19小时) (30 天内合并 384 个 PR)

描述

Before reporting an issue

  • I have read and understood the above terms for submitting issues, and I understand that my issue may be closed without action if I do not follow them.

Area

admin/api

Describe the bug

When updating a user's requiredActions via PUT /admin/realms/{realm}/users/{id}, built-in required actions (members of the UserModel.RequiredAction enum, e.g. UPDATE_PASSWORD, VERIFY_EMAIL) are correctly added and removed. However, custom required actions (registered via the Required Action SPI) are silently ignored when removed from the list.

Adding a custom required action via the same endpoint works correctly.

Version

26.0.1

Regression

  • The issue is a regression

Expected behavior

PUT with requiredActions: [] (or any list that omits MY_CUSTOM_ACTION) should remove the custom action from the user. No error is indicated, but the action is not removed.

Actual behavior

The custom required action remains on the user after the PUT. Built-in actions (e.g. UPDATE_PASSWORD) in the same list are removed correctly.

How to Reproduce?

import requests

KEYCLOAK_URL = "http://localhost:8080"
REALM        = "master"
TOKEN        = "<admin-token>"

HEADERS = {
    "Authorization": f"Bearer {TOKEN}",
    "Content-Type": "application/json",
}

# 1. Find a user
users = requests.get(
    f"{KEYCLOAK_URL}/admin/realms/{REALM}/users?max=1",
    headers=HEADERS,
).json()
user = users[0]
uid  = user["id"]

# 2. Add a custom required action
user["requiredActions"] = ["MY_CUSTOM_ACTION"]
requests.put(f"{KEYCLOAK_URL}/admin/realms/{REALM}/users/{uid}", json=user, headers=HEADERS)

# Verify: action is present
user = requests.get(f"{KEYCLOAK_URL}/admin/realms/{REALM}/users/{uid}", headers=HEADERS).json()
print(user["requiredActions"])  # → ['MY_CUSTOM_ACTION']  ✓

# 3. Remove the custom required action
user["requiredActions"] = []
resp = requests.put(f"{KEYCLOAK_URL}/admin/realms/{REALM}/users/{uid}", json=user, headers=HEADERS)
print(resp.status_code)  # → 204  (no error)

# Verify: action is still present — BUG
user = requests.get(f"{KEYCLOAK_URL}/admin/realms/{REALM}/users/{uid}", headers=HEADERS).json()
print(user["requiredActions"])  # → ['MY_CUSTOM_ACTION']  ✗ (expected: [])

Anything else?

Environment Keycloak version: 26.0.1 Deployment: Docker / standalone Custom required action registered via `RequiredActionProvider SPI

贡献者指南