test: verify federation keeps the AP1 contract
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
# Google federation without an AP1 application fork
|
||||
|
||||
SPA는 Google SDK나 Google token endpoint를 알지 않는다. 기존 `spa-public`
|
||||
client로 Keycloak authorization endpoint를 호출하고, Keycloak 로그인
|
||||
화면에서 mock Google을 선택해도 callback, PKCE 교환, access token audience,
|
||||
Spring API 호출은 로컬 사용자 로그인과 동일하다.
|
||||
|
||||
달라지는 곳은 Keycloak 앞단뿐이다.
|
||||
|
||||
```text
|
||||
SPA -> Keycloak -> Google/mock OIDC
|
||||
SPA <- Keycloak access token <- Keycloak
|
||||
```
|
||||
|
||||
`verify-federation-spa-zero-change.sh`는 기존 SPA 로그인 버튼에서 broker를
|
||||
선택하고, 변경 없는 callback과 `/api/me`가 200인지 실제 브라우저로 검증한다.
|
||||
@@ -0,0 +1,46 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { chromium } from "playwright-core";
|
||||
|
||||
const password = process.env.MOCK_GOOGLE_USER_PASSWORD;
|
||||
assert.ok(password);
|
||||
|
||||
const browser = await chromium.launch({
|
||||
executablePath: process.env.CHROME_BIN ?? "/usr/bin/google-chrome",
|
||||
headless: true,
|
||||
args: ["--no-sandbox"],
|
||||
});
|
||||
|
||||
try {
|
||||
const page = await browser.newPage();
|
||||
const tokenResponse = page.waitForResponse((response) =>
|
||||
response.url().includes("/protocol/openid-connect/token")
|
||||
&& response.request().postData()?.includes("grant_type=authorization_code"),
|
||||
);
|
||||
|
||||
await page.goto("http://localhost:8088/");
|
||||
await page.locator("#login").click();
|
||||
await page.locator('a[href*="/broker/mock-google/login"]').click();
|
||||
await page.waitForURL(/\/realms\/mock-google\//u);
|
||||
await page.locator("#username").fill("mock-new-user");
|
||||
await page.locator("#password").fill(password);
|
||||
await page.locator("#kc-login").click();
|
||||
|
||||
const response = await tokenResponse;
|
||||
assert.equal(response.status(), 200);
|
||||
const token = (await response.json()).access_token;
|
||||
const payload = JSON.parse(
|
||||
Buffer.from(token.split(".")[1], "base64url").toString(),
|
||||
);
|
||||
assert.match(payload.preferred_username, /^mock-google\./u);
|
||||
assert.ok(payload.aud.includes("keycloak-pattern-api"));
|
||||
|
||||
await page.waitForURL("http://localhost:8088/");
|
||||
await page.locator('[data-authenticated="true"]').waitFor();
|
||||
await page.locator("#call-api").click();
|
||||
await page.waitForFunction(() =>
|
||||
document.querySelector("#result")?.textContent.includes('"httpStatus": 200'),
|
||||
);
|
||||
console.log("Google federation verified with the unchanged AP1 SPA/API contract");
|
||||
} finally {
|
||||
await browser.close();
|
||||
}
|
||||
+2
-1
@@ -5,7 +5,8 @@
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"test:pattern1": "node pattern1.mjs",
|
||||
"test:role-mapping": "node role-mapping.mjs"
|
||||
"test:role-mapping": "node role-mapping.mjs",
|
||||
"test:federation-zero-change": "node federation-zero-change.mjs"
|
||||
},
|
||||
"devDependencies": {
|
||||
"playwright-core": "1.62.0"
|
||||
|
||||
Executable
+11
@@ -0,0 +1,11 @@
|
||||
#!/usr/bin/env sh
|
||||
set -eu
|
||||
|
||||
set -a
|
||||
. ./.env
|
||||
set +a
|
||||
|
||||
./scripts/set-first-broker-login-mode.sh secure
|
||||
npm --prefix e2e ci
|
||||
MOCK_GOOGLE_USER_PASSWORD="$MOCK_GOOGLE_USER_PASSWORD" \
|
||||
npm --prefix e2e run test:federation-zero-change
|
||||
Reference in New Issue
Block a user