(error code: 0x80090308) on session timeouts w/ multiple requests
This is related to #91 and if the proxy is not set to keep alive, multiple requests in a short duration will all fail to authenticate with the message Error: AcceptSecurityContext: SECURITY_STATUS incorrect (<0): (error code: 0x80090308) [invalid token message] because a server context handle could not be found.
If I request now multiple files (after the timeout of the session) using something like:
for (let i = 0; i < 10;i++) {
fetch(`/uri?file=${i}`).then(whatever);
}
all requests will fail. But if i request one first and then the rest (during the session period) everything is fine.
From what I can tell the handle get's added and removed all over again using the configuration values mentioned in #91. I suggest changing the handle name/detection to something different instead of a handle based on the client IP, if possible. There are enough values in the header block that could help creating a more unique handle to search for.
On the other side, if useSession is enabled you could store the serverContextHandle tempoarily inside the session instead of the ServerContextHandleManager.
I have also implemented locally a small addition inside the catch block at auth.js for two of the error codes related to SECURITY_STATUS in cases where the session timed out it triggers 0x80090308 or 0x80090310. If so i just ask the client to auth again using a forward request with Status 308. So fetch() or XMLHttpRequest() create a new session again without any problem. (But only one request for a given IP at a time... :/)
if (opts.useSession && (e.message.includes("(error code: 0x80090310)") || e.message.includes("(error code: 0x80090308)"))) {
schManager.release(req);
delete req.session.sso;
debug("requesting auth again");
res.status(308);
res.set('Location', req.url);
res.end();
} else { /* default */ }
But I'm not sure if this fits for everyone. Header Status 308 tells the client also to ~~resend~~ forward form data and so on.
Today i tried it by adding the Forwarded header in the nginx config using: proxy_set_header Forwarded "for=\"$remote_addr:$remote_port\"";
Using this it seems to work fine on multiple requests at once after the session timed out.
Just dumps of schManager.cache on set/release/get:
Before "Forwarded":
set Map(0) {}
release Map(1) {
'10.81.234.6_close' => {
handle: '****',
timestamp: 1636655728379
}
}
release Map(0) {}
get Map(0) {}
Error: AcceptSecurityContext: SECURITY_STATUS incorrect (<0): (error code: 0x80090308)
release Map(0) {}
set Map(0) {}
Map(1) {
'10.81.234.6_close' => {
handle: '****',
timestamp: 1636655868881
}
}
[...]
After:
release Map(0) {}
get Map(0) {}
set Map(1) {
'for="10.81.234.7:65462"' => {
handle: '****',
timestamp: 1636701143570
}
}
get Map(1) {
'for="10.81.234.7:65462"' => {
handle: '****',
timestamp: 1636701143570
}
}
release Map(1) {
'for="10.81.234.7:65462"' => {
handle: '****',
timestamp: 1636701143570
}
}
get Map(1) {
'for="10.81.234.7:65462"' => {
handle: '****',
timestamp: 1636701143570
}
}
set Map(2) {
'for="10.81.234.7:65462"' => {
handle: '****',
timestamp: 1636701143570
},
'for="10.81.234.7:65464"' => {
handle: '****',
timestamp: 1636701143666
}
}
release Map(2) {
'for="10.81.234.7:65462"' => {
handle: '****',
timestamp: 1636701143570
},
'for="10.81.234.7:65464"' => {
handle: '****',
timestamp: 1636701143666
}
}
get Map(2) {
'for="10.81.234.7:65462"' => {
handle: '****',
timestamp: 1636701143570
},
'for="10.81.234.7:65464"' => {
handle: '****',
timestamp: 1636701143666
}
}
set Map(3) {
'for="10.81.234.7:65462"' => {
handle: '****',
timestamp: 1636701143570
},
'for="10.81.234.7:65464"' => {
handle: '****',
timestamp: 1636701143666
},
'for="10.81.234.7:65468"' => {
handle: '****',
timestamp: 1636701143694
}
}