Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot Post /login/callback #946

Closed
BrendonKupsch1 opened this issue Dec 7, 2024 · 0 comments
Closed

Cannot Post /login/callback #946

BrendonKupsch1 opened this issue Dec 7, 2024 · 0 comments
Labels

Comments

@BrendonKupsch1
Copy link

Any help would be appreciated.
I am trying to create a site that logs in through my University's SSO, which uses SAML2. I can get to the login perfectly, but after a successful login I get routed to my callback URL and get a blank page with the error Cannot POST /login/callback There is no information in the console or SAML tracer other than a 404 error, and logs on the server have not helped either. Any help would be appreciated.

Here is the relevant @node-saml/passport-saml configuration code:

require('dotenv').config(); // Load environment variables
const express = require('express');
const cors = require('cors');
const crypto = require('crypto'); // Import the crypto module
const { client, connectDB } = require('./db/connection'); // Import the client and connectDB
const https = require('https');
const fs = require('fs');
const passport = require('passport');
const SamlStrategy = require('@node-saml/passport-saml').Strategy;
const session = require('express-session');
const bodyParser = require("body-parser");
const morgan = require('morgan'); 


const app = express();

// List of allowed origins
const allowedOrigins = [
    'https://facelect.capping.ecrl.marist.edu',
    'https://api-a1cc77df.duosecurity.com',
    'https://auth.it.marist.edu',
];

app.use(cors());

app.use(express.json()); // Parse incoming JSON data

app.use(morgan('common')); // Log HTTP requests

// Configure session middleware
app.use(session({
    secret: 'your-secret-key',
    resave: false,
    saveUninitialized: true,
    cookie: { secure: process.env.NODE_ENV === 'production' } // Ensure cookies are only used over HTTPS in production
}));

// Initialize Passport and restore authentication state, if any, from the session
app.use(passport.initialize());
app.use(passport.session());

// Connect to the PostgreSQL database
connectDB();

// Function to hash passwords using SHA-256
const hashPassword = (password) => {
    return crypto.createHash('sha256').update(password).digest('hex');
};

// Passport SAML strategy configuration
passport.use(new SamlStrategy(
    {
      callbackUrl: 'https://facelect.capping.ecrl.marist.edu/login/callback',
      entryPoint: 'https://auth.it.marist.edu/idp/profile/SAML2/Redirect/SSO',
      issuer: 'https://facelect.capping.ecrl.marist.edu',
      decryptionPvk: fs.readFileSync('./backend/facelect.capping.ecrl.marist.edu.pem', 'utf-8'),
      privateCert: fs.readFileSync('./backend/2024_facelect.capping.ecrl.marist.edu.pem', 'utf-8'),
      idpCert: fs.readFileSync('./backend/idp_cert.pem', 'utf-8'),
    },
    (profile, done) => {
        // Extract user information from the profile
        const user = {
            email: profile.emailAddress,
        };
        return done(null, user);
    }
));

passport.serializeUser((user, done) => {
    done(null, user);
});

passport.deserializeUser((user, done) => {
    done(null, user);
});

// SSO callback route
app.post(
  'https://facelect.capping.ecrl.marist.edu/login/callback',
  bodyParser.urlencoded({ extended: false }),
  passport.authenticate("saml", {
    failureRedirect: "/",
    failureFlash: true,
  }),
  function (req, res) {
    res.redirect("/user-profile");
  },
);

// SSO login route
app.get('/sso/login', 
    passport.authenticate("saml", { failureRedirect: "/", failureFlash: true }),
    function (req, res) {
        res.redirect("/");
    },
);

// Read SSL certificate and key
const options = {
    key: fs.readFileSync('./backend/facelect.capping.ecrl.marist.edu.pem'),
    cert: fs.readFileSync('./backend/2024_facelect.capping.ecrl.marist.edu.pem'),
    ca: fs.readFileSync('./backend/2024_InCommonCA.crt'),
};

// Create HTTPS server on port 3001
https.createServer(options, app).listen(3001, () => {
    console.log('HTTPS Server running on port 3001');
});

I have attempted to modify the SAML strategy, change how the app.post('/login/callback') logic works, and force just a hello world page at https://my.url.edu/login/callback

I have not been able to solve the Cannot POST /login/callback error

Here is the results when I use curl -v https://facelect.capping.ecrl.marist.edu/login/callback:
`root@MaristFacElectDatabaseVM:~# curl -v https://facelect.capping.ecrl.marist.edu/login/callback

  • Host facelect.capping.ecrl.marist.edu:443 was resolved.
  • IPv6: (none)
  • IPv4: 10.11.29.95, 10.11.29.103
  • Trying 10.11.29.95:443...
  • Connected to facelect.capping.ecrl.marist.edu (10.11.29.95) port 443
  • ALPN: curl offers h2,http/1.1
  • TLSv1.3 (OUT), TLS handshake, Client hello (1):
  • CAfile: /etc/ssl/certs/ca-certificates.crt
  • CApath: /etc/ssl/certs
  • TLSv1.3 (IN), TLS handshake, Server hello (2):
  • TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
  • TLSv1.3 (IN), TLS handshake, Certificate (11):
  • TLSv1.3 (IN), TLS handshake, CERT verify (15):
  • TLSv1.3 (IN), TLS handshake, Finished (20):
  • TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
  • TLSv1.3 (OUT), TLS handshake, Finished (20):
  • SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 / X25519 / RSASSA-PSS
  • ALPN: server accepted http/1.1
  • Server certificate:
  • subject: C=US; ST=New York; O=Marist College; CN=facelect.capping.ecrl.marist.edu
  • start date: Nov 11 00:00:00 2024 GMT
  • expire date: Dec 12 23:59:59 2025 GMT
  • subjectAltName: host "facelect.capping.ecrl.marist.edu" matched cert's "facelect.capping.ecrl.marist.edu"
  • issuer: C=US; O=Internet2; CN=InCommon RSA Server CA 2
  • SSL certificate verify ok.
  • Certificate level 0: Public key type RSA (2048/112 Bits/secBits), signed using sha384WithRSAEncryption
  • Certificate level 1: Public key type RSA (3072/128 Bits/secBits), signed using sha384WithRSAEncryption
  • Certificate level 2: Public key type RSA (4096/152 Bits/secBits), signed using sha384WithRSAEncryption
  • using HTTP/1.x

GET /login/callback HTTP/1.1
Host: facelect.capping.ecrl.marist.edu
User-Agent: curl/8.5.0
Accept: /

  • TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
  • TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
  • old SSL session ID is stale, removing
    < HTTP/1.1 200 OK
    < Date: Sat, 07 Dec 2024 09:05:36 GMT
    < Server: Apache/2.4.58 (Ubuntu)
    < Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
    < X-Powered-By: Express
    < Access-Control-Allow-Origin: *
    < Access-Control-Allow-Methods: *
    < Access-Control-Allow-Headers: *
    < Content-Type: text/html; charset=utf-8
    < Accept-Ranges: bytes
    < Content-Length: 2002
    < ETag: W/"7d2-bycen3y/O2Ae+kFpC7kAuPRhUVM"
    < Vary: Accept-Encoding
    <
@node-saml node-saml locked and limited conversation to collaborators Dec 7, 2024
@markstos markstos converted this issue into discussion #947 Dec 7, 2024

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
Projects
None yet
Development

No branches or pull requests

1 participant