jlguenego / node-expose-sspi

Expose Microsoft Windows SSPI to Node for SSO authentication.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

UnauthorizedError: Error while doing SSO: AcceptSecurityContext: SECURITY_STATUS incorrect

amjayage opened this issue · comments

Hi,

I'm trying to use node-expose-sspi in production for Kerberos authentication. Everything works fine on my development setup, but when I tried it on production, I get the error trace below:

7|index  | 2020-11-26T11:10:16.743Z node-expose-sspi:schManager initCookie
7|index  | 2020-11-26T11:10:16.743Z node-expose-sspi:auth cookieToken:  NEGOTIATE_7978678688
7|index  | 2020-11-26T11:10:16.743Z node-expose-sspi:auth no authorization key in header
7|index  | 2020-11-26T11:10:16.775Z node-expose-sspi:schManager initCookie
7|index  | 2020-11-26T11:10:16.775Z node-expose-sspi:auth cookieToken:  NEGOTIATE_7978678688
7|index  | 2020-11-26T11:10:16.775Z node-expose-sspi:misc buffer length 1710
7|index  | 2020-11-26T11:10:16.775Z node-expose-sspi:auth messageType:  Kerberos_1
7|index  | 2020-11-26T11:10:16.775Z node-expose-sspi:misc buffer length 1710
7|index  | 2020-11-26T11:10:16.775Z node-expose-sspi:auth <Long chunk of hexadecimals>
7|index  | 2020-11-26T11:10:16.775Z node-expose-sspi:schManager wait for release with cookie NEGOTIATE_7978678688
7|index  | 2020-11-26T11:10:16.775Z node-expose-sspi:auth schManager waitForReleased finished.
7|index  | 2020-11-26T11:10:16.775Z node-expose-sspi:schManager cookieToken:  NEGOTIATE_7978678688
7|index  | 2020-11-26T11:10:16.775Z node-expose-sspi:auth set cookie bug management
7|index  | 2020-11-26T11:10:16.775Z node-expose-sspi:auth input just before calling AcceptSecurityContext {
7|index  |   credential: '<hexadecimal string>.<hexadecimal string>',
7|index  |   SecBufferDesc: { ulVersion: 0, buffers: [ [ArrayBuffer] ] },
7|index  |   contextHandle: '0x000002a225ebf6b0.0x0000019cf4b62f60'
7|index  | }
7|index  | Error: AcceptSecurityContext: SECURITY_STATUS incorrect (<0): (error code: 0x80090308) The token supplied to the function is invalid
7|index  |     at F:\Backend\node_modules\node-expose-sspi\dist\sso\auth.js:116:58
7|index  | 2020-11-26T11:10:16.775Z node-expose-sspi:adConnection openADConnection: counter:  1
7|index  | 2020-11-26T11:10:16.790Z node-expose-sspi:adConnection closeADConnection: counter:  0
7|index  | statusInfo:  {
7|index  |   adminPrivileges: false,
7|index  |   isOnDomain: true,
7|index  |   domain: 'MYDOMAIN',
7|index  |   isActiveDirectoryReachable: true
7|index  | }
7|index  | messageType:  Kerberos_1
7|index  | UnauthorizedError: Error while doing SSO: AcceptSecurityContext: SECURITY_STATUS incorrect (<0): (error code: 0x80090308) The token supplied to the function is invalid
7|index  |     at F:\Backend\node_modules\node-expose-sspi\dist\sso\auth.js:177:43

Additional context

  • Browser: Internet Explorer 11
  • node-expose-sspi (version 0.1.51) is used with ExpressJS (runs on PM2)
  • Client uses ReactJS and runs on IIS 10
  • IIS reverse proxy is used for ExpressJS

Hope you can advise on how I can solve this problem. Thanks.

It says that the Kerberos token sent by IIS is invalid. It is probably because the Domain Administrator needs to set the SPN (Service Principal Name) on the windows domain account that runs the server.
Please could you check the SPN ? You can also see the windows setspn command.

Hi @jlguenego, thanks for the reply. I checked using the setspn command, and the SPN HTTP\<FQDN of web app> is set on the domain account that is running the ExpressJS server.

It should be HTTP/<FQDN> and not HTTP\<FQDN>. Could you retry ?

Apologies, the \ in my previous comment may have been a typo, but I'm not in office right now to do another check. I'll check whether it's / or \ when I'm back in office next Mon/Tue and get back to you again.

Thanks and have a great weekend.

no worries. I think I will use this issue to investigate how I can automatically check the application is well configured about the SPN.

I made a typo in my comment last week, the SPN is HTTP/<FQDN>. Are there any other possible causes for this error?

Hi @jlguenego, I'm now able to get pass the invalid token error. However, I now face the following error and I'm not sure what went wrong:

3|index  | 2020-12-08T07:05:22.225Z node-expose-sspi:schManager initCookie
3|index  | 2020-12-08T07:05:22.226Z node-expose-sspi:auth cookieToken:  NEGOTIATE_5513448212
3|index  | 2020-12-08T07:05:22.226Z node-expose-sspi:auth no authorization key in header
3|index  | 2020-12-08T07:05:22.274Z node-expose-sspi:schManager initCookie
3|index  | 2020-12-08T07:05:22.274Z node-expose-sspi:auth cookieToken:  NEGOTIATE_5513448212
3|index  | 2020-12-08T07:05:22.274Z node-expose-sspi:misc buffer length 1836
3|index  | 2020-12-08T07:05:22.277Z node-expose-sspi:auth messageType:  Kerberos_1
3|index  | 2020-12-08T07:05:22.277Z node-expose-sspi:misc buffer length 1836
3|index  | 2020-12-08T07:05:22.279Z node-expose-sspi:auth <big chunk of hexa>
3|index  | 2020-12-08T07:05:22.279Z node-expose-sspi:schManager wait for release with cookie NEGOTIATE_5513448212
3|index  | 2020-12-08T07:05:22.279Z node-expose-sspi:auth schManager waitForReleased finished.
3|index  | 2020-12-08T07:05:22.279Z node-expose-sspi:schManager cookieToken:  NEGOTIATE_5513448212
3|index  | 2020-12-08T07:05:22.279Z node-expose-sspi:auth set cookie bug management
3|index  | 2020-12-08T07:05:22.279Z node-expose-sspi:auth input just before calling AcceptSecurityContext {
3|index  |   credential: '<hexa>.<hexa>',
3|index  |   SecBufferDesc: { ulVersion: 0, buffers: [ [ArrayBuffer] ] },
3|index  |   contextHandle: undefined
3|index  | }
3|index  | 2020-12-08T07:05:22.283Z node-expose-sspi:auth serverSecurityContext just after AcceptSecurityContext {
3|index  |   contextHandle: '<hexa>.<hexa>',
3|index  |   contextAttr: [
3|index  |     'ASC_RET_MUTUAL_AUTH',
3|index  |     'ASC_RET_CONNECTION',
3|index  |     'ASC_RET_EXTENDED_ERROR',
3|index  |     'ASC_RET_INTEGRITY'
3|index  |   ],
3|index  |   SecBufferDesc: { ulVersion: 0, buffers: [ [ArrayBuffer] ] },
3|index  |   SECURITY_STATUS: 'SEC_I_CONTINUE_NEEDED'
3|index  | }
3|index  | 2020-12-08T07:05:22.284Z node-expose-sspi:auth AcceptSecurityContext output buffer
3|index  | 2020-12-08T07:05:22.284Z node-expose-sspi:misc buffer length 136
3|index  | 2020-12-08T07:05:22.284Z node-expose-sspi:auth <big chunk of hexa>
3|index  | 2020-12-08T07:05:22.298Z node-expose-sspi:schManager cookieToken:  NEGOTIATE_5513448212
3|index  | 2020-12-08T07:05:22.299Z node-expose-sspi:auth adding to input a serverContextHandle (not first exchange)
3|index  | 2020-12-08T07:05:22.299Z node-expose-sspi:auth input just before calling AcceptSecurityContext {
3|index  |   credential: '<hexa>.<hexa>',
3|index  |   SecBufferDesc: { ulVersion: 0, buffers: [ [ArrayBuffer] ] },
3|index  |   contextHandle: '<hexa>.<hexa>'
3|index  | }
3|index  | 2020-12-08T07:05:22.300Z node-expose-sspi:auth serverSecurityContext just after AcceptSecurityContext {
3|index  |   contextHandle: '<hexa>.<hexa>',
3|index  |   contextAttr: [ 'ASC_RET_MUTUAL_AUTH', 'ASC_RET_CONNECTION', 'ASC_RET_INTEGRITY' ],
3|index  |   SecBufferDesc: { ulVersion: 0, buffers: [ [ArrayBuffer] ] },
3|index  |   SECURITY_STATUS: 'SEC_I_CONTINUE_NEEDED'
3|index  | }
3|index  | 2020-12-08T07:05:22.300Z node-expose-sspi:auth AcceptSecurityContext output buffer
3|index  | 2020-12-08T07:05:22.300Z node-expose-sspi:misc buffer length 204
3|index  | 2020-12-08T07:05:22.301Z node-expose-sspi:auth <big chunk of hexa>
3|index  | 2020-12-08T07:05:22.324Z node-expose-sspi:schManager initCookie
3|index  | 2020-12-08T07:05:22.324Z node-expose-sspi:auth cookieToken:  NEGOTIATE_5513448212
3|index  | 2020-12-08T07:05:22.324Z node-expose-sspi:misc buffer length 41
3|index  | 2020-12-08T07:05:22.324Z node-expose-sspi:auth messageType:  Kerberos_N
3|index  | 2020-12-08T07:05:22.324Z node-expose-sspi:misc buffer length 41
3|index  | 2020-12-08T07:05:22.324Z node-expose-sspi:auth <big chunk of hexa>
3|index  | 2020-12-08T07:05:22.324Z node-expose-sspi:schManager cookieToken:  NEGOTIATE_5513448212
3|index  | 2020-12-08T07:05:22.324Z node-expose-sspi:auth adding to input a serverContextHandle (not first exchange)
3|index  | 2020-12-08T07:05:22.324Z node-expose-sspi:auth input just before calling AcceptSecurityContext {
3|index  |   credential: '<hexa>.<hexa>',
3|index  |   SecBufferDesc: { ulVersion: 0, buffers: [ [ArrayBuffer] ] },
3|index  |   contextHandle: '<hexa>.<hexa>'
3|index  | }
3|index  | 2020-12-08T07:05:22.326Z node-expose-sspi:auth serverSecurityContext just after AcceptSecurityContext {
3|index  |   contextHandle: '<hexa>.<hexa>',
3|index  |   contextAttr: [ 'ASC_RET_MUTUAL_AUTH', 'ASC_RET_CONNECTION', 'ASC_RET_INTEGRITY' ],
3|index  |   SecBufferDesc: { ulVersion: 0, buffers: [ [ArrayBuffer] ] },
3|index  |   SECURITY_STATUS: 'SEC_E_OK'
3|index  | }
3|index  | 2020-12-08T07:05:22.326Z node-expose-sspi:auth AcceptSecurityContext output buffer
3|index  | 2020-12-08T07:05:22.328Z node-expose-sspi:misc buffer length 0
3|index  | 2020-12-08T07:05:22.328Z node-expose-sspi:auth
3|index  | 2020-12-08T07:05:22.328Z node-expose-sspi:schManager cookieToken:  NEGOTIATE_5513448212
3|index  | 2020-12-08T07:05:22.330Z node-expose-sspi:SSO this.options.useGroups:  true
3|index  | 2020-12-08T07:05:22.330Z node-expose-sspi:SSO about to do GetTokenInformation
3|index  | 2020-12-08T07:05:22.343Z node-expose-sspi:SSO groups:  <All local and AD groups>
3|index  | 2020-12-08T07:05:22.344Z node-expose-sspi:SSO about to do CloseHandle
3|index  | 2020-12-08T07:05:22.344Z node-expose-sspi:SSO about to do LookupAccountName
3|index  | 2020-12-08T07:05:22.345Z node-expose-sspi:SSO about to do isOnDomain and isActiveDirectoryReachable
3|index  | 2020-12-08T07:05:22.346Z node-expose-sspi:adConnection openADConnection: counter:  1
3|index  | 2020-12-08T07:05:22.477Z node-expose-sspi:adConnection closeADConnection: counter:  0
3|index  | 2020-12-08T07:05:22.479Z node-expose-sspi:SSO about to do getUser
3|index  | 2020-12-08T07:05:22.480Z node-expose-sspi:userdb getUser start
3|index  | 2020-12-08T07:05:22.480Z node-expose-sspi:mutex acquire
3|index  | Error: write UNKNOWN
3|index  |     at process.target._send (internal/child_process.js:806:20)
3|index  |     at process.target.send (internal/child_process.js:677:19)
3|index  |     at process.send (F:\npm-global\node_modules\pm2\lib\ProcessContainer.js:51:21)
3|index  |     at SyncWriteStream.write (F:\npm-global\node_modules\pm2\lib\ProcessContainer.js:195:17)
3|index  |     at Function.log (F:\Backend\node_modules\node-expose-sspi\node_modules\debug\src\node.js:194:24)
3|index  |     at debug (F:\Backend\node_modules\node-expose-sspi\node_modules\debug\src\common.js:111:10)
3|index  |     at SSO.load (F:\Backend\node_modules\node-expose-sspi\dist\sso\SSO.js:30:9)
3|index  |     at F:\Backend\node_modules\node-expose-sspi\dist\sso\auth.js:146:27
3|index  |     at F:\Backend\node_modules\node-expose-sspi\dist\sso\auth.js:179:11
3|index  |     at Layer.handle [as handle_request] (F:\Backend\node_modules\express\lib\router\layer.js:95:5)

Could you advise on how I should go about solving this problem? Thanks.

First of all, please upgrade the node-expose-sspi to the very last version.
Second, the error seems to be raised while doing the getUser function which try to get user info from the active directory. May be you should check the access right to the Active Directory. The domain windows account running the node http server should have the right to read any info from the active directory.

Hope that helps.

I added in the 0.1.55 the debugging of the Kerberos KRB_AP_REQ message: I can extract the realm and the principal name of the token sent to the server by the client. So I debug it (set DEBUG=node-expose-sspi:* to get it).

I added also the list of all declared principal name on the domain, so it is easy now to check if a sysadmin did not set properly the principal names.

Thanks, I will give the new version a try tomorrow and see if I can find the problem. I don't think it's a problem with access rights since I was able to obtain the groups that the logged in user belongs to from the AD.

Hello, I managed to solve the problem on production. It turns out that for some unknown reason, there was an error with the getUser function when I run my Express server using PM2 on production. This did not happen on my staging environment.

By running my server without PM2, I was able to get the Kerberos authentication working. Thanks for your help!