Merged
This commit is contained in:
parent
14b0b29386
commit
c3c09856bc
@ -1,7 +1,5 @@
|
|||||||
# Mock SAML from BoxyHQ
|
# Mock SAML from BoxyHQ
|
||||||
|
|
||||||
http://localhost:4000/apps/saml?RelayState&SAMLRequest=
|
|
||||||
|
|
||||||
- Parse the SAML Request
|
- Parse the SAML Request
|
||||||
- Create the SAML Response
|
- Create the SAML Response
|
||||||
- Fix the certificate
|
- Fix the certificate
|
||||||
@ -1,4 +1,14 @@
|
|||||||
/** @type {import('next').NextConfig} */
|
/** @type {import('next').NextConfig} */
|
||||||
module.exports = {
|
module.exports = {
|
||||||
reactStrictMode: true,
|
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",
|
"axios": "^0.24.0",
|
||||||
"next": "12.0.10",
|
"next": "12.0.10",
|
||||||
"node-fetch": "^3.2.0",
|
"node-fetch": "^3.2.0",
|
||||||
|
"rambda": "^7.0.2",
|
||||||
"react": "17.0.2",
|
"react": "17.0.2",
|
||||||
"react-dom": "17.0.2",
|
"react-dom": "17.0.2",
|
||||||
"rsuite": "^5.5.2",
|
"rsuite": "^5.5.2",
|
||||||
|
"webpack-filter-warnings-plugin": "^1.2.1",
|
||||||
"xml2js": "^0.4.23",
|
"xml2js": "^0.4.23",
|
||||||
"xmlbuilder": "^15.1.1"
|
"xmlbuilder": "^15.1.1"
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import type { NextApiRequest, NextApiResponse } from 'next';
|
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||||
import { createCertificate, createIdPMetadataXML } from '../../../../utils';
|
import { createCertificate, createIdPMetadataXML, createIdPSSOUrl } from '../../../../utils';
|
||||||
import { IdPMetadata } from '../../../../types';
|
import { IdPMetadata } from '../../../../types';
|
||||||
import stream from 'stream';
|
import stream from 'stream';
|
||||||
import { promisify } from 'util';
|
import { promisify } from 'util';
|
||||||
@ -25,7 +25,7 @@ export default async function handler(
|
|||||||
|
|
||||||
const xml = await createIdPMetadataXML({
|
const xml = await createIdPMetadataXML({
|
||||||
idpEntityId: config.entityId,
|
idpEntityId: config.entityId,
|
||||||
idpSsoUrl: `${config.appUrl}/saml2/app/${appId}`,
|
idpSsoUrl: createIdPSSOUrl(appId),
|
||||||
certificate: await createCertificate(),
|
certificate: await createCertificate(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import type { NextApiRequest, NextApiResponse } from 'next';
|
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||||
import { createCertificate } from '../../../../utils';
|
import { createCertificate, createIdPSSOUrl } from '../../../../utils';
|
||||||
import { IdPMetadata } from '../../../../types';
|
import { IdPMetadata } from '../../../../types';
|
||||||
import config from '../../../../lib/env'
|
import config from '../../../../lib/env'
|
||||||
|
|
||||||
@ -23,7 +23,7 @@ export default async function handler(
|
|||||||
const metadata = {
|
const metadata = {
|
||||||
certificate: await createCertificate(),
|
certificate: await createCertificate(),
|
||||||
fingerprint: '',
|
fingerprint: '',
|
||||||
sso_url: `${config.appUrl}/saml2/app/${appId}`,
|
sso_url: createIdPSSOUrl(appId),
|
||||||
entity_id: config.entityId,
|
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 = {
|
export type AuthNRequest = {
|
||||||
RelayState: string;
|
relayState: string;
|
||||||
SAMLRequest: SAMLRequest;
|
samlRequest: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type User = {
|
export type User = {
|
||||||
|
|||||||
@ -3,6 +3,8 @@ import { promises as fs } from 'fs';
|
|||||||
import path from 'path';
|
import path from 'path';
|
||||||
import xml2js from 'xml2js';
|
import xml2js from 'xml2js';
|
||||||
import { User } from '../types';
|
import { User } from '../types';
|
||||||
|
import config from '../lib/env';
|
||||||
|
import * as rambda from 'rambda';
|
||||||
|
|
||||||
// Parse XML
|
// Parse XML
|
||||||
const parseXML = (xml: string): Promise<Record<string, any>> => {
|
const parseXML = (xml: string): Promise<Record<string, any>> => {
|
||||||
@ -13,17 +15,17 @@ const parseXML = (xml: string): Promise<Record<string, any>> => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// Extract SAML Request Attributes
|
// Parse SAMLRequest attributes
|
||||||
const extractSAMLRequestAttributes = async (SAMLRequest: string | string[]) => {
|
const extractSAMLRequestAttributes = async (samlRequest: string) => {
|
||||||
// @ts-ignore
|
// @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']['$'];
|
const attributes = result['samlp:AuthnRequest']['$'];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
ID: attributes['ID'],
|
id: attributes['ID'],
|
||||||
IssueInstant: attributes['IssueInstant'],
|
issueInstant: attributes['IssueInstant'],
|
||||||
AssertionConsumerServiceURL: attributes['AssertionConsumerServiceURL'],
|
acsUrl: attributes['AssertionConsumerServiceURL'],
|
||||||
ProviderName: attributes['ProviderName'],
|
providerName: attributes['ProviderName'],
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -74,6 +76,10 @@ const createSAMLResponseXML = async (user: User): Promise<string> => {
|
|||||||
.replace('user_lastName', 'K');
|
.replace('user_lastName', 'K');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const createIdPSSOUrl = (appId: string) => {
|
||||||
|
return `${config.appUrl}/saml2/apps/${appId}`;
|
||||||
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
parseXML,
|
parseXML,
|
||||||
extractSAMLRequestAttributes,
|
extractSAMLRequestAttributes,
|
||||||
@ -81,4 +87,5 @@ export {
|
|||||||
createSAMLResponseXML,
|
createSAMLResponseXML,
|
||||||
createCertificate,
|
createCertificate,
|
||||||
extractCert,
|
extractCert,
|
||||||
|
createIdPSSOUrl,
|
||||||
};
|
};
|
||||||
Loading…
Reference in New Issue
Block a user