Derive the Keycloak URL from the gateway's stored OIDC issuer. The server validates the issuer claim in JWTs, so the token must be requested from the same base URL the server was configured with (typically the host IP, not localhost).
()
| 33 | |
| 34 | |
| 35 | def _keycloak_url() -> str: |
| 36 | """Derive the Keycloak URL from the gateway's stored OIDC issuer. |
| 37 | |
| 38 | The server validates the issuer claim in JWTs, so the token must be |
| 39 | requested from the same base URL the server was configured with |
| 40 | (typically the host IP, not localhost). |
| 41 | """ |
| 42 | if url := os.environ.get("OPENSHELL_KEYCLOAK_URL"): |
| 43 | return url |
| 44 | cluster_name = os.environ.get("OPENSHELL_GATEWAY", "openshell") |
| 45 | metadata_path = ( |
| 46 | _xdg_config_home() / "openshell" / "gateways" / cluster_name / "metadata.json" |
| 47 | ) |
| 48 | if metadata_path.exists(): |
| 49 | metadata = json.loads(metadata_path.read_text()) |
| 50 | issuer = metadata.get("oidc_issuer", "") |
| 51 | if issuer: |
| 52 | # issuer is like "http://192.168.4.172:8180/realms/openshell" |
| 53 | # extract base URL before /realms/ |
| 54 | idx = issuer.find("/realms/") |
| 55 | if idx > 0: |
| 56 | return issuer[:idx] |
| 57 | return "http://localhost:8180" |
| 58 | |
| 59 | |
| 60 | TOKEN_ENDPOINT = ( |
no test coverage detected