tngan / samlify

Node.js library for SAML SSO
https://samlify.js.org
MIT License
601 stars 214 forks source link

Nextjs + Samlify (Request Param on ParseLoginRequest) #531

Open boncz92 opened 6 months ago

boncz92 commented 6 months ago

Also posted this on the nextjs issues board but as typically its a bit slow to get a response I wanted to put it out here to see if anyone has a solution

When im attempting to migrate from nextjs page router to the app router im encountering an error. It seems that the error is being caused by the change in how the 'request' object is handled prior to getting ahold of it. The first example returns parsed results as expected while the second example returns an error:

' TypeError [ERR_INVALID_ARG_TYPE]: The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object. Received undefined'

This is obviously a way in which samlify is handling the parsing of the request object passed to it (There isnt an option to just pass it the 'samlResponse') it expects a normally structured unaltered response object passed to it. Is there a way to either recreate the expected structure, or pass it just the saml response object from the request?

/pages/api/auth/samlAuth.js

    import fs from 'fs';
    import * as saml from 'samlify';
    import * as saml_validator from '@authenio/samlify-validate-with-xmllint';

    const ServiceProvider = saml.ServiceProvider;
    const IdentityProvider = saml.IdentityProvider;

    const SAMLMetaDataSP = fs.readFileSync(process.env.SAMLMetaDataSP);
    const SAMLMetaDataIDP = fs.readFileSync(process.env.SAMLMetaDataIDP);

    const samlSP = ServiceProvider({
        metadata: SAMLMetaDataSP,
    });

    const samlIDP = IdentityProvider({
        metadata: SAMLMetaDataIDP,
    });

    saml.setSchemaValidator(saml_validator);

    export default async function handler(req, res) {
        const method = req.method

    let UserInformation = {};
        await samlSP.parseLoginResponse(samlIDP, 'post', req)
            .then(async parsedResults => {
                console.log(parsedResults)
            })
            .catch(err => {
                console.log(err)
                console.log("Error")
            })

        return res.json({ UserInformation })
    }

/app/api/samlAuth/route.js

    import fs from 'fs';
    import * as saml from 'samlify';
    import * as saml_validator from '@authenio/samlify-validate-with-xmllint';

    const ServiceProvider = saml.ServiceProvider;
    const IdentityProvider = saml.IdentityProvider;

    const SAMLMetaDataSP = fs.readFileSync(process.env.SAMLMetaDataSP);
    const SAMLMetaDataIDP = fs.readFileSync(process.env.SAMLMetaDataIDP);

    const samlSP = ServiceProvider({
        metadata: SAMLMetaDataSP,
    });

    const samlIDP = IdentityProvider({
        metadata: SAMLMetaDataIDP,
    });

    saml.setSchemaValidator(saml_validator);

    export async function POST(request) {
        const method = request.method
        const referer = request.headers.get('referer')

        let UserInformation = {};
        await samlSP.parseLoginResponse(samlIDP, 'post', request)
            .then(async parsedResults => {
                console.log(parsedResults)
            })
            .catch(err => {
                console.log(err)
                console.log("Error")
            })

        return Response.json({ UserInformation })
    }

    export async function GET() {
        const data = { Test: true }

        return Response.json({ data })
    }