Multiple JWT Auth Strategies not Working
See original GitHub issueIn our application, we have multiple types of JWTs that we authenticate with; from users, and from applications for instance, and each type is valid for a (potentially overlapping) subset of routes. Looking through the documentation, it seemed as tho the best approach for handling this would be to have two separate strategies for each type, and apply those strategies to the routes as appropriate, however, it appears that only the first strategy listed is ever run.
My strategies are configured as follows:
server.auth.strategy('userJwt', 'jwt', {
key: require('./utils/keyLookup'),
//validateFunc: require('./utils/authJwtValidate'),
verifyFunc: require('./utils/authJwtValidate')
});
server.auth.strategy('applicationJwt', 'jwt', {
key: conf.get('jwtSigningToken'),
validateFunc: require('./utils/applicationJwtValidate'),
verifyOptions: {
issuer: false
}
});
Each strategy works fine by itself.
An example route that should be able to authenticate with either type of JWT follows:
server.route([
{
method: 'GET',
path: '/v2/projects',
config: {
auth: {
strategies: ['userJwt', 'applicationJwt']
},
handler: projectsController.index,
...
}
},
...
]);
However, when the route is hit, only the first listed authentication strategy is run, and if it fails, the server immediately responds with a 401, rather than moving on to trying the next one. Am I missing something about how multiple configured authentication strategies is meant to work?
Thanks in advance, -Taylor
Issue Analytics
- State:
- Created 7 years ago
- Reactions:1
- Comments:14 (4 by maintainers)
One part of the code that I think should change has to do with the error handling for the initial checks for validity of the token. I’m looking at
index.js:117
andindex.js:126
. I would suggest changing them to set the message to null, rather than to'Invalid token format'
, as is done atindex.js:113
.The reason for this is that by setting a message, you prevent any subsequent auth strategies from being run, which may be incorrect behavior. For a concrete example, suppose you have a route that can be authenticated via either basic auth or JWT auth.
Under the route config you have:
And a user comes in with valid basic auth credentials:
The authenticate function is called, and the token exists, so the condition on line 113 is not met. Instead, the token validity check fails, and the return statement on line 117 is called. Since this sets the message of the unauthorized error, Hapi will immediately reply to the request with a 401 error, even tho the user had valid credentials for basic auth.
If instead those two return statements did not set a message on the 401 response, the next strategy (the basic auth, in this example) would be executed.
As an update. I’ve found that in my use case putting a custom errorFunc will workaround it if anyone can’t wait for the PR to get approved, etc.
errorFunc: (errorContext) => { errorContext.message = null; return errorContext; }