fix: return browser-accessible Logto URL from /api/config
Separate LOGTO_PUBLIC_ENDPOINT (browser-facing, defaults to http://localhost:3001) from LOGTO_ENDPOINT (Docker-internal). Also fix bootstrap M2M verification by using correct Host header for default tenant token endpoint. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -11,6 +11,7 @@ POSTGRES_DB=cameleer_saas
|
|||||||
|
|
||||||
# Logto Identity Provider
|
# Logto Identity Provider
|
||||||
LOGTO_ENDPOINT=http://logto:3001
|
LOGTO_ENDPOINT=http://logto:3001
|
||||||
|
LOGTO_PUBLIC_ENDPOINT=http://localhost:3001
|
||||||
LOGTO_ISSUER_URI=http://logto:3001/oidc
|
LOGTO_ISSUER_URI=http://logto:3001/oidc
|
||||||
LOGTO_JWK_SET_URI=http://logto:3001/oidc/jwks
|
LOGTO_JWK_SET_URI=http://logto:3001/oidc/jwks
|
||||||
LOGTO_DB_PASSWORD=change_me_in_production
|
LOGTO_DB_PASSWORD=change_me_in_production
|
||||||
|
|||||||
@@ -92,6 +92,7 @@ services:
|
|||||||
SPRING_DATASOURCE_USERNAME: ${POSTGRES_USER:-cameleer}
|
SPRING_DATASOURCE_USERNAME: ${POSTGRES_USER:-cameleer}
|
||||||
SPRING_DATASOURCE_PASSWORD: ${POSTGRES_PASSWORD:-cameleer_dev}
|
SPRING_DATASOURCE_PASSWORD: ${POSTGRES_PASSWORD:-cameleer_dev}
|
||||||
LOGTO_ENDPOINT: ${LOGTO_ENDPOINT:-http://logto:3001}
|
LOGTO_ENDPOINT: ${LOGTO_ENDPOINT:-http://logto:3001}
|
||||||
|
LOGTO_PUBLIC_ENDPOINT: ${LOGTO_PUBLIC_ENDPOINT:-http://localhost:3001}
|
||||||
LOGTO_ISSUER_URI: ${LOGTO_ISSUER_URI:-http://logto:3001/oidc}
|
LOGTO_ISSUER_URI: ${LOGTO_ISSUER_URI:-http://logto:3001/oidc}
|
||||||
LOGTO_JWK_SET_URI: ${LOGTO_JWK_SET_URI:-http://logto:3001/oidc/jwks}
|
LOGTO_JWK_SET_URI: ${LOGTO_JWK_SET_URI:-http://logto:3001/oidc/jwks}
|
||||||
LOGTO_M2M_CLIENT_ID: ${LOGTO_M2M_CLIENT_ID:-}
|
LOGTO_M2M_CLIENT_ID: ${LOGTO_M2M_CLIENT_ID:-}
|
||||||
|
|||||||
@@ -47,15 +47,22 @@ M_DEFAULT_SECRET=$(PGPASSWORD="${PG_PASSWORD:-cameleer_dev}" psql -h "$PG_HOST"
|
|||||||
log "Got m-default secret."
|
log "Got m-default secret."
|
||||||
|
|
||||||
# --- Get Management API token ---
|
# --- Get Management API token ---
|
||||||
get_token() {
|
get_admin_token() {
|
||||||
curl -s -X POST "${LOGTO_ADMIN_ENDPOINT}/oidc/token" \
|
curl -s -X POST "${LOGTO_ADMIN_ENDPOINT}/oidc/token" \
|
||||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||||
-H "Host: localhost:3002" \
|
-H "Host: localhost:3002" \
|
||||||
-d "grant_type=client_credentials&client_id=${1}&client_secret=${2}&resource=${MGMT_API_RESOURCE}&scope=all"
|
-d "grant_type=client_credentials&client_id=${1}&client_secret=${2}&resource=${MGMT_API_RESOURCE}&scope=all"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get_default_token() {
|
||||||
|
curl -s -X POST "${LOGTO_ENDPOINT}/oidc/token" \
|
||||||
|
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||||
|
-H "Host: localhost:3001" \
|
||||||
|
-d "grant_type=client_credentials&client_id=${1}&client_secret=${2}&resource=${MGMT_API_RESOURCE}&scope=all"
|
||||||
|
}
|
||||||
|
|
||||||
log "Getting Management API token..."
|
log "Getting Management API token..."
|
||||||
TOKEN_RESPONSE=$(get_token "m-default" "$M_DEFAULT_SECRET")
|
TOKEN_RESPONSE=$(get_admin_token "m-default" "$M_DEFAULT_SECRET")
|
||||||
log "Token response: $(echo "$TOKEN_RESPONSE" | head -c 200)"
|
log "Token response: $(echo "$TOKEN_RESPONSE" | head -c 200)"
|
||||||
TOKEN=$(echo "$TOKEN_RESPONSE" | jq -r '.access_token' 2>/dev/null)
|
TOKEN=$(echo "$TOKEN_RESPONSE" | jq -r '.access_token' 2>/dev/null)
|
||||||
[ -z "$TOKEN" ] || [ "$TOKEN" = "null" ] && { log "ERROR: Failed to get token"; exit 1; }
|
[ -z "$TOKEN" ] || [ "$TOKEN" = "null" ] && { log "ERROR: Failed to get token"; exit 1; }
|
||||||
@@ -137,7 +144,7 @@ else
|
|||||||
log "Assigned Management API role to M2M app."
|
log "Assigned Management API role to M2M app."
|
||||||
|
|
||||||
# Verify our M2M app works
|
# Verify our M2M app works
|
||||||
VERIFY=$(get_token "$M2M_ID" "$M2M_SECRET")
|
VERIFY=$(get_default_token "$M2M_ID" "$M2M_SECRET")
|
||||||
VERIFY_TOKEN=$(echo "$VERIFY" | jq -r '.access_token')
|
VERIFY_TOKEN=$(echo "$VERIFY" | jq -r '.access_token')
|
||||||
if [ -n "$VERIFY_TOKEN" ] && [ "$VERIFY_TOKEN" != "null" ]; then
|
if [ -n "$VERIFY_TOKEN" ] && [ "$VERIFY_TOKEN" != "null" ]; then
|
||||||
log "Verified M2M app works."
|
log "Verified M2M app works."
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ public class PublicConfigController {
|
|||||||
private static final Logger log = LoggerFactory.getLogger(PublicConfigController.class);
|
private static final Logger log = LoggerFactory.getLogger(PublicConfigController.class);
|
||||||
private static final String BOOTSTRAP_FILE = "/data/bootstrap/logto-bootstrap.json";
|
private static final String BOOTSTRAP_FILE = "/data/bootstrap/logto-bootstrap.json";
|
||||||
|
|
||||||
@Value("${cameleer.identity.logto-endpoint:}")
|
@Value("${cameleer.identity.logto-public-endpoint:${cameleer.identity.logto-endpoint:}}")
|
||||||
private String logtoEndpoint;
|
private String logtoPublicEndpoint;
|
||||||
|
|
||||||
@Value("${cameleer.identity.spa-client-id:}")
|
@Value("${cameleer.identity.spa-client-id:}")
|
||||||
private String spaClientId;
|
private String spaClientId;
|
||||||
@@ -34,8 +34,8 @@ public class PublicConfigController {
|
|||||||
clientId = readBootstrapClientId();
|
clientId = readBootstrapClientId();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use external Logto endpoint for browser redirects
|
// Use public endpoint for browser redirects (not Docker-internal URL)
|
||||||
String endpoint = logtoEndpoint;
|
String endpoint = logtoPublicEndpoint;
|
||||||
if (endpoint == null || endpoint.isEmpty()) {
|
if (endpoint == null || endpoint.isEmpty()) {
|
||||||
endpoint = "http://localhost:3001";
|
endpoint = "http://localhost:3001";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ cameleer:
|
|||||||
public-key-path: ${CAMELEER_JWT_PUBLIC_KEY_PATH:}
|
public-key-path: ${CAMELEER_JWT_PUBLIC_KEY_PATH:}
|
||||||
identity:
|
identity:
|
||||||
logto-endpoint: ${LOGTO_ENDPOINT:}
|
logto-endpoint: ${LOGTO_ENDPOINT:}
|
||||||
|
logto-public-endpoint: ${LOGTO_PUBLIC_ENDPOINT:}
|
||||||
m2m-client-id: ${LOGTO_M2M_CLIENT_ID:}
|
m2m-client-id: ${LOGTO_M2M_CLIENT_ID:}
|
||||||
m2m-client-secret: ${LOGTO_M2M_CLIENT_SECRET:}
|
m2m-client-secret: ${LOGTO_M2M_CLIENT_SECRET:}
|
||||||
spa-client-id: ${LOGTO_SPA_CLIENT_ID:}
|
spa-client-id: ${LOGTO_SPA_CLIENT_ID:}
|
||||||
|
|||||||
Reference in New Issue
Block a user