feat: map Keycloak realm roles to Spring RBAC

This commit is contained in:
donghyeon-ka
2026-07-25 16:35:28 +09:00
parent f566ed192c
commit 3e3de6c4c3
9 changed files with 202 additions and 2 deletions
+2 -1
View File
@@ -4,7 +4,8 @@
"version": "1.0.0",
"type": "module",
"scripts": {
"test:pattern1": "node pattern1.mjs"
"test:pattern1": "node pattern1.mjs",
"test:role-mapping": "node role-mapping.mjs"
},
"devDependencies": {
"playwright-core": "1.62.0"
+65
View File
@@ -0,0 +1,65 @@
import assert from "node:assert/strict";
import { chromium } from "playwright-core";
const keycloakUrl = "http://localhost:8080";
const frontendUrl = "http://localhost:8088/";
async function accessToken(browser, username, password) {
const context = await browser.newContext();
const page = await context.newPage();
await page.goto(frontendUrl);
const tokenResponse = page.waitForResponse((response) =>
response.url().includes("/protocol/openid-connect/token")
&& response.request().postData()?.includes("grant_type=authorization_code"),
);
await page.locator("#login").click();
await page.locator("#username").fill(username);
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;
await context.close();
return token;
}
async function adminStatus(token) {
return (
await fetch("http://localhost:8081/api/admin", {
headers: { Authorization: `Bearer ${token}` },
})
).status;
}
const regularPassword = process.env.REGULAR_USER_PASSWORD;
const adminPassword = process.env.ADMIN_USER_PASSWORD;
assert.ok(regularPassword && adminPassword);
const browser = await chromium.launch({
executablePath: process.env.CHROME_BIN ?? "/usr/bin/google-chrome",
headless: true,
args: ["--no-sandbox"],
});
try {
const regularToken = await accessToken(
browser,
"regular-user",
regularPassword,
);
const regularPayload = JSON.parse(
Buffer.from(regularToken.split(".")[1], "base64url").toString(),
);
assert.ok(regularPayload.realm_access.roles.includes("user-role"));
assert.equal(await adminStatus(regularToken), 403);
const adminToken = await accessToken(browser, "admin-user", adminPassword);
const adminPayload = JSON.parse(
Buffer.from(adminToken.split(".")[1], "base64url").toString(),
);
assert.ok(adminPayload.realm_access.roles.includes("admin-role"));
assert.equal(await adminStatus(adminToken), 200);
console.log("Spring RBAC verified: realm role -> ROLE_ authority -> 403/200");
} finally {
await browser.close();
}