Merged
This commit is contained in:
parent
14b0b29386
commit
c3c09856bc
@ -1,7 +1,5 @@
|
||||
# Mock SAML from BoxyHQ
|
||||
|
||||
http://localhost:4000/apps/saml?RelayState&SAMLRequest=
|
||||
|
||||
- Parse the SAML Request
|
||||
- Create the SAML Response
|
||||
- Fix the certificate
|
||||
- Create the SAML Response
|
||||
- Fix the certificate
|
||||
|
||||
@ -1,4 +1,14 @@
|
||||
/** @type {import('next').NextConfig} */
|
||||
module.exports = {
|
||||
reactStrictMode: true,
|
||||
webpack: (config, { isServer }) => {
|
||||
if (!isServer) {
|
||||
config.resolve.fallback = {
|
||||
fs: false,
|
||||
zlib: false,
|
||||
}
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
}
|
||||
|
||||
8140
package-lock.json
generated
8140
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -12,9 +12,11 @@
|
||||
"axios": "^0.24.0",
|
||||
"next": "12.0.10",
|
||||
"node-fetch": "^3.2.0",
|
||||
"rambda": "^7.0.2",
|
||||
"react": "17.0.2",
|
||||
"react-dom": "17.0.2",
|
||||
"rsuite": "^5.5.2",
|
||||
"webpack-filter-warnings-plugin": "^1.2.1",
|
||||
"xml2js": "^0.4.23",
|
||||
"xmlbuilder": "^15.1.1"
|
||||
},
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||
import { createCertificate, createIdPMetadataXML } from '../../../../utils';
|
||||
import { createCertificate, createIdPMetadataXML, createIdPSSOUrl } from '../../../../utils';
|
||||
import { IdPMetadata } from '../../../../types';
|
||||
import stream from 'stream';
|
||||
import { promisify } from 'util';
|
||||
@ -25,7 +25,7 @@ export default async function handler(
|
||||
|
||||
const xml = await createIdPMetadataXML({
|
||||
idpEntityId: config.entityId,
|
||||
idpSsoUrl: `${config.appUrl}/saml2/app/${appId}`,
|
||||
idpSsoUrl: createIdPSSOUrl(appId),
|
||||
certificate: await createCertificate(),
|
||||
});
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||
import { createCertificate } from '../../../../utils';
|
||||
import { createCertificate, createIdPSSOUrl } from '../../../../utils';
|
||||
import { IdPMetadata } from '../../../../types';
|
||||
import config from '../../../../lib/env'
|
||||
|
||||
@ -23,7 +23,7 @@ export default async function handler(
|
||||
const metadata = {
|
||||
certificate: await createCertificate(),
|
||||
fingerprint: '',
|
||||
sso_url: `${config.appUrl}/saml2/app/${appId}`,
|
||||
sso_url: createIdPSSOUrl(appId),
|
||||
entity_id: config.entityId,
|
||||
}
|
||||
|
||||
|
||||
@ -1,42 +0,0 @@
|
||||
import type { NextPage } from 'next';
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
|
||||
export async function getServerSideProps(context: any) {
|
||||
const {RelayState, SAMLRequest} = context.query;
|
||||
|
||||
return {
|
||||
props: {
|
||||
RelayState: RelayState,
|
||||
SAMLRequest: SAMLRequest
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// const createSAMLResponse = ({RelayState, SAMLRequest}: Prop) => {
|
||||
// const url = new URL('http://28a2-103-153-104-43.ngrok.io/sso/acs');
|
||||
|
||||
// url.searchParams.append('RelayState', RelayState);
|
||||
// url.searchParams.append('SAMLResponse', 'SAMLResponse');
|
||||
|
||||
// return url.href;
|
||||
// }
|
||||
|
||||
const SAML: NextPage = (prop) => {
|
||||
const [] = useState();
|
||||
const formRef = useRef(null);
|
||||
|
||||
useEffect(() => {
|
||||
// @ts-ignore
|
||||
formRef?.current?.submit();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<form action="http://28a2-103-153-104-43.ngrok.io/sso/acs" method="POST" ref={formRef}>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SAML;
|
||||
38
pages/saml2/apps/[appid].tsx
Normal file
38
pages/saml2/apps/[appid].tsx
Normal file
@ -0,0 +1,38 @@
|
||||
import type { GetServerSideProps } from 'next';
|
||||
import React from "react";
|
||||
import { AuthNRequest } from '../../../types'
|
||||
import {extractSAMLRequestAttributes} from '../../../utils'
|
||||
|
||||
export const getServerSideProps: GetServerSideProps = async ({query, params}) => {
|
||||
const relayState = query.RelayState as string;
|
||||
const samlRequest = query.SAMLRequest as string;
|
||||
|
||||
const attributes = await extractSAMLRequestAttributes(samlRequest);
|
||||
|
||||
console.log(attributes)
|
||||
|
||||
return {
|
||||
props: {
|
||||
relayState,
|
||||
samlRequest,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
const ProcessRequest: React.FC<AuthNRequest> = ({relayState, samlRequest}) => {
|
||||
|
||||
|
||||
return (
|
||||
<div>Process Request</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default ProcessRequest;
|
||||
|
||||
// Start a session
|
||||
// Store the RelayState in the session
|
||||
// Parse the SAMLRequest
|
||||
// Validate the SAMLRequest
|
||||
// Create SAMLResponse
|
||||
// POST the SAMLResponse to ACS URL
|
||||
// Remove the RelayState from the session
|
||||
@ -27,8 +27,8 @@ export type SAMLRequest = {
|
||||
};
|
||||
|
||||
export type AuthNRequest = {
|
||||
RelayState: string;
|
||||
SAMLRequest: SAMLRequest;
|
||||
relayState: string;
|
||||
samlRequest: string;
|
||||
};
|
||||
|
||||
export type User = {
|
||||
|
||||
@ -3,6 +3,8 @@ import { promises as fs } from 'fs';
|
||||
import path from 'path';
|
||||
import xml2js from 'xml2js';
|
||||
import { User } from '../types';
|
||||
import config from '../lib/env';
|
||||
import * as rambda from 'rambda';
|
||||
|
||||
// Parse XML
|
||||
const parseXML = (xml: string): Promise<Record<string, any>> => {
|
||||
@ -13,17 +15,17 @@ const parseXML = (xml: string): Promise<Record<string, any>> => {
|
||||
});
|
||||
};
|
||||
|
||||
// Extract SAML Request Attributes
|
||||
const extractSAMLRequestAttributes = async (SAMLRequest: string | string[]) => {
|
||||
// Parse SAMLRequest attributes
|
||||
const extractSAMLRequestAttributes = async (samlRequest: string) => {
|
||||
// @ts-ignore
|
||||
const result = await parseXML(Buffer.from(SAMLRequest, 'base64').toString());
|
||||
const result = await parseXML(Buffer.from(samlRequest, 'base64').toString());
|
||||
const attributes = result['samlp:AuthnRequest']['$'];
|
||||
|
||||
return {
|
||||
ID: attributes['ID'],
|
||||
IssueInstant: attributes['IssueInstant'],
|
||||
AssertionConsumerServiceURL: attributes['AssertionConsumerServiceURL'],
|
||||
ProviderName: attributes['ProviderName'],
|
||||
id: attributes['ID'],
|
||||
issueInstant: attributes['IssueInstant'],
|
||||
acsUrl: attributes['AssertionConsumerServiceURL'],
|
||||
providerName: attributes['ProviderName'],
|
||||
};
|
||||
};
|
||||
|
||||
@ -74,6 +76,10 @@ const createSAMLResponseXML = async (user: User): Promise<string> => {
|
||||
.replace('user_lastName', 'K');
|
||||
};
|
||||
|
||||
const createIdPSSOUrl = (appId: string) => {
|
||||
return `${config.appUrl}/saml2/apps/${appId}`;
|
||||
}
|
||||
|
||||
export {
|
||||
parseXML,
|
||||
extractSAMLRequestAttributes,
|
||||
@ -81,4 +87,5 @@ export {
|
||||
createSAMLResponseXML,
|
||||
createCertificate,
|
||||
extractCert,
|
||||
};
|
||||
createIdPSSOUrl,
|
||||
};
|
||||
Loading…
Reference in New Issue
Block a user