Store OIDC config in cookie instead of URL
This commit is contained in:
parent
239e39e5ed
commit
33b352c3ef
|
@ -6,6 +6,7 @@ exports.UserStatus = {
|
|||
exports.Cookies = {
|
||||
CurrentApp: "budibase:currentapp",
|
||||
Auth: "budibase:auth",
|
||||
OIDC_CONFIG: "budibase:oidc:config",
|
||||
}
|
||||
|
||||
exports.GlobalRoles = {
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
import Auth0Logo from "assets/auth0-logo.png"
|
||||
import MicrosoftLogo from "assets/microsoft-logo.png"
|
||||
|
||||
import { admin, oidc } from "stores/portal"
|
||||
import { oidc } from "stores/portal"
|
||||
import { onMount } from "svelte"
|
||||
|
||||
let show = false
|
||||
|
@ -27,7 +27,8 @@
|
|||
|
||||
{#if show}
|
||||
<ActionButton
|
||||
on:click={() => window.open(`/api/admin/auth/oidc/${$oidc.uuid}`, "_blank")}
|
||||
on:click={() =>
|
||||
window.open(`/api/admin/auth/oidc/configs/${$oidc.uuid}`, "_blank")}
|
||||
>
|
||||
<div class="inner">
|
||||
<img {src} alt="oidc icon" />
|
||||
|
|
|
@ -79,10 +79,6 @@
|
|||
providers.oidc?.config?.configs[0].clientID &&
|
||||
providers.oidc?.config?.configs[0].clientSecret
|
||||
|
||||
$: oidcCallback = providers.oidc?.config.configs[0].uuid
|
||||
? `/api/admin/auth/oidc/callback/${providers.oidc?.config.configs[0].uuid}`
|
||||
: ""
|
||||
|
||||
async function uploadLogo(file) {
|
||||
let data = new FormData()
|
||||
data.append("file", file)
|
||||
|
@ -240,7 +236,7 @@
|
|||
{/each}
|
||||
<div class="form-row">
|
||||
<Label size="L">Callback URL</Label>
|
||||
<Input readonly bind:value={oidcCallback} />
|
||||
<Input readonly placeholder="/api/admin/auth/oidc/callback" />
|
||||
</div>
|
||||
<br />
|
||||
<Body size="S">
|
||||
|
|
|
@ -4,7 +4,8 @@ const { oidc } = require("@budibase/auth/src/middleware")
|
|||
const { Configs, EmailTemplatePurpose } = require("../../../constants")
|
||||
const CouchDB = require("../../../db")
|
||||
const { sendEmail, isEmailConfigured } = require("../../../utilities/email")
|
||||
const { clearCookie, getGlobalUserByEmail, hash } = authPkg.utils
|
||||
const { setCookie, getCookie, clearCookie, getGlobalUserByEmail, hash } =
|
||||
authPkg.utils
|
||||
const { Cookies } = authPkg.constants
|
||||
const { passport } = authPkg.auth
|
||||
const { checkResetPasswordCode } = require("../../../utilities/redis")
|
||||
|
@ -133,9 +134,7 @@ exports.googleAuth = async (ctx, next) => {
|
|||
)(ctx, next)
|
||||
}
|
||||
|
||||
async function oidcStrategyFactory(ctx) {
|
||||
const { configId } = ctx.params
|
||||
|
||||
async function oidcStrategyFactory(ctx, configId) {
|
||||
const db = new CouchDB(GLOBAL_DB)
|
||||
|
||||
const config = await authPkg.db.getScopedConfig(db, {
|
||||
|
@ -145,7 +144,7 @@ async function oidcStrategyFactory(ctx) {
|
|||
|
||||
const chosenConfig = config.configs.filter(c => c.uuid === configId)[0]
|
||||
|
||||
const callbackUrl = `${ctx.protocol}://${ctx.host}/api/admin/auth/oidc/callback/${configId}`
|
||||
const callbackUrl = `${ctx.protocol}://${ctx.host}/api/admin/auth/oidc/callback`
|
||||
|
||||
return oidc.strategyFactory(chosenConfig, callbackUrl)
|
||||
}
|
||||
|
@ -155,7 +154,10 @@ async function oidcStrategyFactory(ctx) {
|
|||
* On a successful login, you will be redirected to the oidcAuth callback route.
|
||||
*/
|
||||
exports.oidcPreAuth = async (ctx, next) => {
|
||||
const strategy = await oidcStrategyFactory(ctx)
|
||||
const { configId } = ctx.params
|
||||
const strategy = await oidcStrategyFactory(ctx, configId)
|
||||
|
||||
setCookie(ctx, configId, Cookies.OIDC_CONFIG)
|
||||
|
||||
return passport.authenticate(strategy, {
|
||||
// required 'openid' scope is added by oidc strategy factory
|
||||
|
@ -164,7 +166,8 @@ exports.oidcPreAuth = async (ctx, next) => {
|
|||
}
|
||||
|
||||
exports.oidcAuth = async (ctx, next) => {
|
||||
const strategy = await oidcStrategyFactory(ctx)
|
||||
const configId = getCookie(ctx, Cookies.OIDC_CONFIG)
|
||||
const strategy = await oidcStrategyFactory(ctx, configId)
|
||||
|
||||
return passport.authenticate(
|
||||
strategy,
|
||||
|
|
|
@ -39,7 +39,7 @@ router
|
|||
.post("/api/admin/auth/logout", authController.logout)
|
||||
.get("/api/admin/auth/google", authController.googlePreAuth)
|
||||
.get("/api/admin/auth/google/callback", authController.googleAuth)
|
||||
.get("/api/admin/auth/oidc/:configId", authController.oidcPreAuth)
|
||||
.get("/api/admin/auth/oidc/callback/:configId", authController.oidcAuth)
|
||||
.get("/api/admin/auth/oidc/configs/:configId", authController.oidcPreAuth)
|
||||
.get("/api/admin/auth/oidc/callback", authController.oidcAuth)
|
||||
|
||||
module.exports = router
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
const setup = require("./utilities")
|
||||
const { Cookies } = require("@budibase/auth").constants
|
||||
|
||||
jest.mock("nodemailer")
|
||||
const sendMailMock = setup.emailMock()
|
||||
|
@ -74,13 +75,13 @@ describe("/api/admin/auth", () => {
|
|||
afterEach(() => {
|
||||
expect(strategyFactory).toBeCalledWith(
|
||||
chosenConfig,
|
||||
`http://127.0.0.1:4003/api/admin/auth/oidc/callback/${configId}` // calculated url
|
||||
`http://127.0.0.1:4003/api/admin/auth/oidc/callback` // calculated url
|
||||
)
|
||||
})
|
||||
|
||||
describe("/api/admin/auth/oidc", () => {
|
||||
describe("/api/admin/auth/oidc/configs", () => {
|
||||
it("should load strategy and delegate to passport", async () => {
|
||||
await request.get(`/api/admin/auth/oidc/${configId}`)
|
||||
await request.get(`/api/admin/auth/oidc/configs/${configId}`)
|
||||
|
||||
expect(passportSpy).toBeCalledWith(mockStrategyReturn, {
|
||||
scope: ["profile", "email"],
|
||||
|
@ -91,7 +92,8 @@ describe("/api/admin/auth", () => {
|
|||
|
||||
describe("/api/admin/auth/oidc/callback", () => {
|
||||
it("should load strategy and delegate to passport", async () => {
|
||||
await request.get(`/api/admin/auth/oidc/callback/${configId}`)
|
||||
await request.get(`/api/admin/auth/oidc/callback`)
|
||||
.set(config.getOIDConfigCookie(configId))
|
||||
|
||||
expect(passportSpy).toBeCalledWith(mockStrategyReturn, {
|
||||
successRedirect: "/", failureRedirect: "/error"
|
||||
|
|
|
@ -68,6 +68,12 @@ class TestConfiguration {
|
|||
}
|
||||
}
|
||||
|
||||
cookieHeader(cookies) {
|
||||
return {
|
||||
Cookie: [cookies],
|
||||
}
|
||||
}
|
||||
|
||||
defaultHeaders() {
|
||||
const user = {
|
||||
_id: "us_uuid1",
|
||||
|
@ -77,7 +83,7 @@ class TestConfiguration {
|
|||
const authToken = jwt.sign(user, env.JWT_SECRET)
|
||||
return {
|
||||
Accept: "application/json",
|
||||
Cookie: [`${Cookies.Auth}=${authToken}`],
|
||||
...this.cookieHeader([`${Cookies.Auth}=${authToken}`]),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -156,6 +162,11 @@ class TestConfiguration {
|
|||
)
|
||||
}
|
||||
|
||||
getOIDConfigCookie(configId) {
|
||||
const token = jwt.sign(configId, env.JWT_SECRET)
|
||||
return this.cookieHeader([[`${Cookies.OIDC_CONFIG}=${token}`]])
|
||||
}
|
||||
|
||||
async saveOIDCConfig() {
|
||||
await this.deleteConfig(Configs.OIDC)
|
||||
const config = {
|
||||
|
|
Loading…
Reference in New Issue