From 7ad7ec0186dc263231808ad29f36833cc60c5ea0 Mon Sep 17 00:00:00 2001 From: Deepak Prabhakara Date: Sun, 21 Jan 2024 01:01:09 +0000 Subject: [PATCH] fixed namespace login (#473) --- lib/entity-id.ts | 6 +++++- lib/env.ts | 2 -- pages/api/namespace/[namespace]/saml/sso.ts | 3 +++ pages/api/saml/metadata.ts | 4 ++-- pages/api/saml/sso.ts | 4 +++- pages/index.tsx | 10 ++++++---- 6 files changed, 19 insertions(+), 10 deletions(-) create mode 100644 pages/api/namespace/[namespace]/saml/sso.ts diff --git a/lib/entity-id.ts b/lib/entity-id.ts index 57e5cee..848d4d0 100644 --- a/lib/entity-id.ts +++ b/lib/entity-id.ts @@ -2,4 +2,8 @@ const getEntityId = (entityId: string, namespace: string | undefined) => { return namespace ? `${entityId}/${namespace}` : entityId; }; -export { getEntityId }; +const getSSOUrl = (appUrl: string, namespace: string | undefined) => { + return `${appUrl}/api` + (namespace ? `/namespace/${namespace}` : '') + '/saml/sso'; +}; + +export { getEntityId, getSSOUrl }; diff --git a/lib/env.ts b/lib/env.ts index 16c6610..ca9d189 100644 --- a/lib/env.ts +++ b/lib/env.ts @@ -2,14 +2,12 @@ import { fetchPrivateKey, fetchPublicKey } from 'utils'; const appUrl = process.env.APP_URL || 'http://localhost:4000'; const entityId = process.env.ENTITY_ID || 'https://saml.example.com/entityid'; -const ssoUrl = `${appUrl}/api/saml/sso`; const privateKey = fetchPrivateKey(); const publicKey = fetchPublicKey(); const config = { appUrl, entityId, - ssoUrl, privateKey, publicKey, }; diff --git a/pages/api/namespace/[namespace]/saml/sso.ts b/pages/api/namespace/[namespace]/saml/sso.ts new file mode 100644 index 0000000..44c5909 --- /dev/null +++ b/pages/api/namespace/[namespace]/saml/sso.ts @@ -0,0 +1,3 @@ +import handler from 'pages/api/saml/sso'; + +export default handler; diff --git a/pages/api/saml/metadata.ts b/pages/api/saml/metadata.ts index 40bb8c3..91e5e83 100644 --- a/pages/api/saml/metadata.ts +++ b/pages/api/saml/metadata.ts @@ -6,7 +6,7 @@ import type { IdPMetadata } from 'types'; import { createIdPMetadataXML } from 'utils'; import stream from 'stream'; import { promisify } from 'util'; -import { getEntityId } from 'lib/entity-id'; +import { getEntityId, getSSOUrl } from 'lib/entity-id'; const pipeline = promisify(stream.pipeline); @@ -26,7 +26,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse< const xml = await createIdPMetadataXML({ idpEntityId: getEntityId(config.entityId, req.query.namespace as any), - idpSsoUrl: config.ssoUrl, + idpSsoUrl: getSSOUrl(config.appUrl, req.query.namespace as any), certificate: saml.stripCertHeaderAndFooter(config.publicKey), }); diff --git a/pages/api/saml/sso.ts b/pages/api/saml/sso.ts index 0815140..78a9b0f 100644 --- a/pages/api/saml/sso.ts +++ b/pages/api/saml/sso.ts @@ -46,7 +46,9 @@ async function processSAMLRequest(req: NextApiRequest, res: NextApiResponse, isP const params = new URLSearchParams({ id, audience, acsUrl, providerName, relayState }); - res.redirect(302, `/saml/login?${params.toString()}`); + const loginUrl = (req.query.namespace ? `/namespace/${req.query.namespace}` : '') + '/saml/login'; + + res.redirect(302, `${loginUrl}?${params.toString()}`); } catch (err) { console.error(err); diff --git a/pages/index.tsx b/pages/index.tsx index 63f3f3f..ef3f0f6 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -3,16 +3,18 @@ import Link from 'next/link'; import React from 'react'; import config from '../lib/env'; import { IdPMetadata } from '../types'; -import { getEntityId } from 'lib/entity-id'; +import { getEntityId, getSSOUrl } from 'lib/entity-id'; const Home: React.FC<{ metadata: IdPMetadata; params: any }> = ({ metadata, params }) => { const namespace = params.namespace; - const { ssoUrl, entityId, certificate } = metadata; + const { ssoUrl: appUrl, entityId, certificate } = metadata; const namespaceEntityId = getEntityId(entityId, namespace); const metadataDownloadUrl = '/api' + (namespace ? `/namespace/${namespace}` : '') + '/saml/metadata?download=true'; const metadataUrl = '/api' + (namespace ? `/namespace/${namespace}` : '') + '/saml/metadata'; + const loginUrl = (namespace ? `/namespace/${namespace}` : '') + '/saml/login'; + const ssoUrl = getSSOUrl(appUrl, namespace); return (
@@ -41,7 +43,7 @@ const Home: React.FC<{ metadata: IdPMetadata; params: any }> = ({ metadata, para Metadata URL
- + Test IdP Login
@@ -83,7 +85,7 @@ const Home: React.FC<{ metadata: IdPMetadata; params: any }> = ({ metadata, para export const getServerSideProps: GetServerSideProps = async ({ params }) => { const metadata: IdPMetadata = { - ssoUrl: config.ssoUrl, + ssoUrl: config.appUrl, entityId: config.entityId, certificate: config.publicKey, };