Updated Admin API key auth to require kid in header (#10538)

* Required kid be a header claim as according to spec

https://tools.ietf.org/html/rfc7515#section-4.1.4 (JWT is an extension of JWS)

* Updated error message for missing kid

* Fixed admin-api key unit tests

* Fixed regression and acceptance tests
This commit is contained in:
Fabien O'Carroll 2019-02-26 05:03:47 +01:00 committed by Hannah Wolfe
parent 71951eabea
commit 4e6a6a24ac
5 changed files with 13 additions and 15 deletions

View File

@ -60,12 +60,12 @@ const authenticate = (req, res, next) => {
}));
}
const apiKeyId = decoded.payload.kid;
const apiKeyId = decoded.header.kid;
if (!apiKeyId) {
return next(new common.errors.BadRequestError({
message: common.i18n.t('errors.middleware.auth.adminApiKeyMissing'),
code: 'MISSING_ADMIN_API_KEY'
message: common.i18n.t('errors.middleware.auth.adminApiKidMissing'),
code: 'MISSING_ADMIN_API_KID'
}));
}

View File

@ -86,7 +86,7 @@
"authorizationFailed": "Authorization failed",
"missingContentMemberOrIntegration": "Unable to determine the authenticated member or integration. Check the supplied Content API Key and ensure cookies are being passed through if member auth is failing.",
"missingAdminUserOrIntegration": "Unable to determine the authenticated user or integration. Check that cookies are being passed through if using session authentication.",
"adminApiKeyMissing": "Admin API Key missing.",
"adminApiKeyMissing": "Admin API Token missing kid header claim.",
"unknownAdminApiKey": "Unknown Admin API Key",
"unknownContentApiKey": "Unknown Content API Key",
"invalidApiKeyType": "Invalid API Key type",

View File

@ -128,15 +128,14 @@ module.exports = {
getValidAdminToken(audience) {
const jwt = require('jsonwebtoken');
const JWT_OPTIONS = {
keyid: testUtils.DataGenerator.Content.api_keys[0].id,
algorithm: 'HS256',
expiresIn: '5m',
audience: audience
};
return jwt.sign(
{
kid: testUtils.DataGenerator.Content.api_keys[0].id
},
{},
Buffer.from(testUtils.DataGenerator.Content.api_keys[0].secret, 'hex'),
JWT_OPTIONS
);

View File

@ -104,15 +104,14 @@ module.exports = {
getValidAdminToken(endpoint) {
const jwt = require('jsonwebtoken');
const JWT_OPTIONS = {
keyid: testUtils.DataGenerator.Content.api_keys[0].id,
algorithm: 'HS256',
expiresIn: '5m',
audience: endpoint
};
return jwt.sign(
{
kid: testUtils.DataGenerator.Content.api_keys[0].id
},
{},
Buffer.from(testUtils.DataGenerator.Content.api_keys[0].secret, 'hex'),
JWT_OPTIONS
);

View File

@ -33,8 +33,8 @@ describe('Admin API Key Auth', function () {
it('should authenticate known+valid API key', function (done) {
const token = jwt.sign({
kid: this.fakeApiKey.id
}, this.secret, {
keyid: this.fakeApiKey.id,
algorithm: 'HS256',
expiresIn: '5m',
audience: '/v2/admin/',
@ -94,8 +94,8 @@ describe('Admin API Key Auth', function () {
it('shouldn\'t authenticate with invalid/unknown key', function (done) {
const token = jwt.sign({
kid: 'unknown'
}, this.secret, {
keyid: 'unknown',
algorithm: 'HS256',
expiresIn: '5m',
audience: 'wrong audience',
@ -121,10 +121,10 @@ describe('Admin API Key Auth', function () {
it('shouldn\'t authenticate with JWT signed > 5min ago', function (done) {
const payload = {
kid: this.fakeApiKey.id,
iat: Math.floor(Date.now() / 1000) - 6 * 60
};
const token = jwt.sign(payload, this.secret, {
keyid: this.fakeApiKey.id,
algorithm: 'HS256',
expiresIn: '5m',
audience: '/v2/admin/',
@ -151,10 +151,10 @@ describe('Admin API Key Auth', function () {
it('shouldn\'t authenticate with JWT with maxAge > 5min', function (done) {
const payload = {
kid: this.fakeApiKey.id,
iat: Math.floor(Date.now() / 1000) - 6 * 60
};
const token = jwt.sign(payload, this.secret, {
keyid: this.fakeApiKey.id,
algorithm: 'HS256',
expiresIn: '10m',
audience: '/v2/admin/',
@ -181,8 +181,8 @@ describe('Admin API Key Auth', function () {
it('shouldn\'t authenticate with a Content API Key', function (done) {
const token = jwt.sign({
kid: this.fakeApiKey.id
}, this.secret, {
keyid: this.fakeApiKey.id,
algorithm: 'HS256',
expiresIn: '5m',
audience: '/v2/admin/',