Our express js (node) app has an MS OIDC authentication option which is implemented using the passport-azure-ad library. This has been working well for some time in dev on localhost and running on aws behind an application load balancer.
We have just implemented AWS Cloudfront in front of the ALB to serve static content. All working great except the MS OIDC authentication which fails with message.
authentication failed due to: In collectInfoFromReq: invalid state received in the request
It looks like the problem comes in with the POST to the redirect URL.
Use case is multi-tenant login.
Proved it is working well when Cloudfront is bypassed.
All other aspects of the app are working fine behind Cloudfront with this config.
Just wondering if anyone who understands both of these technologies could point us at what is going wrong and how it could be fixed??
Express session setup:
app.use(session({
secret: SESSION_SECRET,
cookie: { maxAge: SESSIONS_EXPIRE, secure: true },
rolling: false, // needs to be manually handled otherwise ping keeps it alive
store: MongoStore.create({
mongoUrl: SESSIONS_SERVER,
mongoOptions: { useNewUrlParser: true, useUnifiedTopology: true },
dbName: SESSIONS_DB,
collectionName: SESSIONS_COLL
}),
resave: true,
saveUninitialized: true
})
MS OIDC Options:
identityMetadata: 'https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration',
clientID: MS_OIDC_CLIENT_ID,
responseType: 'code',
responseMode: 'form_post',
redirectUrl: MS_OIDC_REDIRECT_URL,
allowHttpForRedirectUrl: false,
clientSecret: MS_OIDC_CLIENT_SECRET,
validateIssuer: false,
issuer: MS_OIDC_ISSUER,
passReqToCallback: true,
scope: ["profile"],
loggingLevel: 'info',
useCookieInsteadOfSession: true,
cookieEncryptionKeys: MS_OIDC_COOKIE_KEYS,
cookieSameSite: true,
nonceLifetime: 600,
nonceMaxAmount: 5
AWS Cloudfront has a behaviour configured to send all non-static content to the node alb:-
Compress objects automatically: yes
Viewer: Redirect HTTP to HTTPS
Allowed HTTP methods: GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE
Restrict viewer access: No
Cache Policy: CachingDisabled
POST to redirectURL is received by the app but completion of authentication fails with
authentication failed due to: In collectInfoFromReq: invalid state received in the request
OK resolved this issue with the addition of an Origin Request Policy: AllViewer to the Cloudfront Behaviour that forwards to the app.
Without this, Cloudfront does not pass all headers, cookies and query strings to the origin.