Reputation: 419
We are using hapi-auth-jwt2
alongside jwks-rsa
to decode and verify azureAD access token.
This is our jwt strategy which is active on every route.
'use strict'
const jwt = require('hapi-auth-jwt2')
const jwksRsa = require('jwks-rsa')
const userCtrl = require('./../controllers/UserController')
const authHandler = require('./auth.factory').GetAuthHandler()
// TODO: Replace with current JSON web token formatting and active directory
module.exports = {
name: 'JWT Authentication',
register: async (server, options) => {
await server.register(jwt)
// Confirm that we are getting the correct PK
// const pk = await authHandler.GetPK()
const key = jwksRsa.hapiJwt2KeyAsync({
cache: true,
rateLimit: true,
jwksRequestsPerMinute: 5,
// jwksUri: 'https://YOUR_DOMAIN/.well-known/jwks.json'
jwksUri: 'https://login.microsoftonline.com/common/discovery/keys'
// https://login.microsoftonline.com/common/discovery/keys
// https://login.microsoftonline.com/common/.well-known/openid-configuration
})
server.auth.strategy('jwt', 'jwt', {
// Get the complete decoded token, because we need info from the header (the kid)
complete: true,
// Dynamically provide a signing key based on the kid in the header and the singing keys provided by the JWKS endpoint.
key: key,
// key: pk,
headerKey: 'authorization',
tokenType: 'Bearer',
validate: userCtrl.validate,
verifyOptions: {
algorithms: ['RS256'] // or HS256 RS256
}
})
server.auth.default('jwt')
console.log(key)
}
}
We then attach Authorization
header (i.e. 'Bearer ' + accessToken
) to http
and make a request from locahost
i.e. current client/front-end to the /sso
route and the server comes back with the following request/response
[1569928136140] INFO (11252 on PORT230): request completed
req: {
"id": "1569928136137:PORT230:11264:k17qg99b:10001",
"method": "get",
"url": "https://port230.5874.com/api/v2/user/sso",
"headers": {
"host": "port230.5874.com",
"connection": "keep-alive",
"accept": "application/json, text/plain, */*",
"origin": "http://localhost:8080",
"authorization": "Bearer ...",
"user-agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36",
"sec-fetch-mode": "cors",
"sec-fetch-site": "cross-site",
"referer": "http://localhost:8080/",
"accept-encoding": "gzip, deflate, br",
"accept-language": "en-US,en;q=0.9"
}
}
res: {
"statusCode": 401,
"headers": {
"www-authenticate": "Bearer error=\"Invalid token\"",
"content-type": "application/json; charset=utf-8",
"vary": "origin",
"access-control-allow-origin": "http://localhost:8080",
"access-control-expose-headers": "WWW-Authenticate,Server-Authorization",
"strict-transport-security": "max-age=15768000",
"x-frame-options": "DENY",
"x-xss-protection": "1; mode=block",
"x-download-options": "noopen",
"x-content-type-options": "nosniff",
"cache-control": "no-cache",
"content-length": 106
}
}
responseTime: 3
The response includes "www-authenticate": "Bearer error=\"Invalid token\""
. We have been trying to understand why is there an Invalid Token
error but without much success.
Would anybody know when and why is this error thrown and potentially how to overcome it?
Upvotes: 0
Views: 2360
Reputation: 419
The problem was that we hadn't defined the scopes for our API on https://portal.azure.com correctly. After we fixed that we created API permission with the newly created scope, hence the access token was successfully decoded
Upvotes: 2