Skip to content

Commit 68eb512

Browse files
author
Olivier Gintrand
committed
fix(oauth): MCP OAuth proxy for virtual servers (DCR bypass)
Signed-off-by: Olivier Gintrand <olivier.gintrand@forterro.com>
1 parent a02a04b commit 68eb512

File tree

7 files changed

+837
-6
lines changed

7 files changed

+837
-6
lines changed

mcpgateway/admin.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2950,13 +2950,20 @@ async def admin_add_server(request: Request, db: Session = Depends(get_db), user
29502950
scopes_str = str(form.get("oauth_scopes", "")).strip()
29512951
token_endpoint = str(form.get("oauth_token_endpoint", "")).strip()
29522952

2953+
client_id = str(form.get("oauth_client_id", "")).strip()
2954+
client_secret = str(form.get("oauth_client_secret", "")).strip()
2955+
29532956
if authorization_server:
29542957
oauth_config = {"authorization_servers": [authorization_server]}
29552958
if scopes_str:
29562959
# Convert space-separated scopes to list
29572960
oauth_config["scopes_supported"] = scopes_str.split()
29582961
if token_endpoint:
29592962
oauth_config["token_endpoint"] = token_endpoint
2963+
if client_id:
2964+
oauth_config["client_id"] = client_id
2965+
if client_secret:
2966+
oauth_config["client_secret"] = client_secret
29602967
else:
29612968
# Invalid or incomplete OAuth configuration; disable OAuth to avoid inconsistent state
29622969
LOGGER.warning(
@@ -3111,13 +3118,28 @@ async def admin_edit_server(
31113118
scopes_str = str(form.get("oauth_scopes", "")).strip()
31123119
token_endpoint = str(form.get("oauth_token_endpoint", "")).strip()
31133120

3121+
client_id = str(form.get("oauth_client_id", "")).strip()
3122+
client_secret = str(form.get("oauth_client_secret", "")).strip()
3123+
31143124
if authorization_server:
31153125
oauth_config = {"authorization_servers": [authorization_server]}
31163126
if scopes_str:
31173127
# Convert space-separated scopes to list
31183128
oauth_config["scopes_supported"] = scopes_str.split()
31193129
if token_endpoint:
31203130
oauth_config["token_endpoint"] = token_endpoint
3131+
if client_id:
3132+
oauth_config["client_id"] = client_id
3133+
if client_secret:
3134+
oauth_config["client_secret"] = client_secret
3135+
elif client_id:
3136+
# client_id present but secret left blank in edit form — preserve existing secret
3137+
try:
3138+
existing_server = await server_service.get_server(db, server_id)
3139+
if existing_server.oauth_config and existing_server.oauth_config.get("client_secret"):
3140+
oauth_config["client_secret"] = existing_server.oauth_config["client_secret"]
3141+
except Exception:
3142+
pass
31213143
else:
31223144
# Invalid or incomplete OAuth configuration; disable OAuth to avoid inconsistent state
31233145
LOGGER.warning(

mcpgateway/admin_ui/servers.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -857,6 +857,17 @@ export const editServer = async function (serverId) {
857857
if (oauthTokenEndpointField) {
858858
oauthTokenEndpointField.value = server.oauthConfig.token_endpoint || "";
859859
}
860+
861+
// Extract client_id for DCR bypass (pre-registered client)
862+
const oauthClientIdField = safeGetElement("edit-server-oauth-client-id");
863+
if (oauthClientIdField) {
864+
oauthClientIdField.value = server.oauthConfig.client_id || "";
865+
}
866+
// Clear client_secret field (password field — never pre-filled with actual secret)
867+
const oauthClientSecretField = safeGetElement("edit-server-oauth-client-secret");
868+
if (oauthClientSecretField) {
869+
oauthClientSecretField.value = "";
870+
}
860871
} else {
861872
// Clear OAuth config fields when no config exists
862873
if (oauthAuthServerField) oauthAuthServerField.value = "";

mcpgateway/main.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11149,6 +11149,16 @@ async def cleanup_import_statuses(max_age_hours: int = 24, user=Depends(get_curr
1114911149
except ImportError:
1115011150
logger.debug("OAuth router not available")
1115111151

11152+
# Include MCP OAuth proxy router (virtual server OAuth for MCP clients)
11153+
try:
11154+
# First-Party
11155+
from mcpgateway.routers.mcp_oauth import mcp_oauth_router
11156+
11157+
app.include_router(mcp_oauth_router)
11158+
logger.info("MCP OAuth proxy router included")
11159+
except ImportError:
11160+
logger.debug("MCP OAuth proxy router not available")
11161+
1115211162
# Include reverse proxy router if enabled
1115311163
if settings.mcpgateway_reverse_proxy_enabled:
1115411164
try:

0 commit comments

Comments
 (0)