I am building an API endpoint with Express
, NodeJS
, PassportJS
, and TypeScript
. I want to allow two types of authentication for this endpoint. SAML (for humans) and token for automation. For human authentication, I'm using the passport-saml
strategy. For token auth I'm using passport-http
basic authentication. So far my code looks like:
import session from "express-session";
const samlStrategy = getSamlStrategy();
const basicStrategy = getBasicStrategy();
app.use((req, res, next) =>
session({
// store sessions in db
})(req, res, next)
);
app.use(passport.initialize());
app.use(passport.session());
passport.serializeUser((user, done) => {
//...
});
passport.deserializeUser((username, done) => {
//...
});
passport.use(samlStrategy);
passport.use(basicStrategy);
const requireApiAuth: express.Handler = (req, res, next) => {
if (req.user) {
next();
} else {
res.status(401);
}
};
const tryTokenAuth: express.Handler = (req, res, next) => {
if (!req.user && req.headers.authorization && req.headers.authorization.indexOf("Basic") > -1) {
passport.authenticate("basic", { session: false })(req, res, next);
} else {
next();
}
};
//...
// SAML endpoints here
//...
app.use(
"/api",
tryServiceUserAuth,
requireApiAuth,
The basic idea is the middleware function tryTokenAuth
will check to see if a user
is already present on the request. If there is, then that means a human has already logged in via SAML auth. If there is no user
AND if the request specifies Basic authorization then we should use the basic
strategy to authenticate. At the moment, this is working. I am able to authenticate using either strategy for the /api
route.
The issue is that even though I specify {session: false}
for basic
authentication I'm STILL getting a session cookie sent back in the response. And a session is being recorded in my database. I don't understand what I need to configure to prevent this behavior. I do NOT want a session to be created when basic
auth is used.
Is there any way to accomplish this?
CodePudding user response:
As it turns out specifying session: false
in the call to authenticate only prevents passport
from adding its session data to a request session. The reason a session is still being created is because my config says:
app.use((req, res, next) =>
session({
// store sessions in db
})(req, res, next)
);
In order to prevent this when using basic auth I had to update to:
app.use((req, res, next) => {
if (req.headers.authorization && req.headers.authorization.indexOf("Basic") > -1) {
next();
} else {
session({
// store sessions in db
})(req, res, next)
}
});