Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added API Key authentication middleware to v2 API routes #9915

Closed

Conversation

kevinansfield
Copy link
Contributor

@kevinansfield kevinansfield commented Sep 26, 2018

refs #9865

  • add auth.authenticate.authenticateAdminApiKey middleware
    • accepts signed JWT in an Authorization: Ghost [token] header
    • sets req.api_key if the token is valid
  • add auth.authenticate.authenticateContentApiKey middleware
    • accepts ?content_key= query param, sets req.api_key if it's a known Content API key
  • add requiresAuthorizedUserOrApiKey authorization middleware
    • passes if either req.user or req.api_key exists
  • update authenticatePrivate middleware stack for v2 admin routes
  • update authenticatePublic middleware stack for v2 content routes

Split out from #9869 for easier review.

TODO:

  • remove oauth2 specific Bearer in Authorization header
  • extract rejectAdminKey and rejectContentKey into separate middlewares
  • add comment documenting authenticateAdminApiKey flow
  • add authenticateContentApiKey middleware to v2 content API routes
  • i18n error messages
  • remove rejectAdminKey and rejectContentKey middleware
  • rebase and update to work with session auth

Copy link
Contributor

@allouis allouis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! There's a few minor comments and questions 👍


/**
* Remove 'Bearer' from raw authorization header and extract the JWT token.
* Eg. Authorization: Bearer ${JWT}

This comment was marked as abuse.

This comment was marked as abuse.

This comment was marked as abuse.

core/server/services/auth/api-key/admin.js Show resolved Hide resolved
};

const authenticateAdminApiKey = function authenticateAdminApiKey(req, res, next) {
if (req.query && req.query.content_key) {

This comment was marked as abuse.

This comment was marked as abuse.

}

// unknown error
return next(new common.errors.InternalServerError(err));

This comment was marked as abuse.

This comment was marked as abuse.

This comment was marked as abuse.

} = require('../../../lib/common/errors');

const authenticateContentApiKey = function authenticateContentApiKey(req, res, next) {
if (req.headers && req.headers.authorization) {

This comment was marked as abuse.

This comment was marked as abuse.

@@ -0,0 +1,4 @@
module.exports = {
admin: require('./admin'),

This comment was marked as abuse.

This comment was marked as abuse.

core/server/web/api/v2/admin/app.js Show resolved Hide resolved
"description": "Blog Owner"
},
{
"name": "Admin API Client",

This comment was marked as abuse.

This comment was marked as abuse.

This comment was marked as abuse.

validations: {isLength: {min: 128, max: 128}}
},
role_id: {type: 'string', maxlength: 24, nullable: true},
integration_id: {type: 'string', maxlength: 24, nullable: true},

This comment was marked as abuse.

This comment was marked as abuse.

This comment was marked as abuse.

@@ -0,0 +1,33 @@
const commands = require('../../../schema').commands;

This comment was marked as abuse.

This comment was marked as abuse.

This comment was marked as abuse.

This comment was marked as abuse.

This comment was marked as abuse.

@kirrg001 kirrg001 self-assigned this Sep 27, 2018
@kirrg001 kirrg001 changed the title Added API Key authentication middleware to v2 API routes [WIP] Added API Key authentication middleware to v2 API routes Sep 27, 2018
@kevinansfield kevinansfield force-pushed the api-key/authentication branch 2 times, most recently from 3577149 to ecca55f Compare September 27, 2018 13:32
@kirrg001 kirrg001 changed the title [WIP] Added API Key authentication middleware to v2 API routes [HOLD] Added API Key authentication middleware to v2 API routes Sep 27, 2018
@kevinansfield kevinansfield changed the title [HOLD] Added API Key authentication middleware to v2 API routes [WIP] Added API Key authentication middleware to v2 API routes Oct 2, 2018
@kevinansfield kevinansfield force-pushed the api-key/authentication branch 2 times, most recently from 4ddbeec to cc00d67 Compare October 3, 2018 10:34
return;
};

const rejectAdminApiKey = function rejectAdminApiKey(req, res, next) {

This comment was marked as abuse.

This comment was marked as abuse.

This comment was marked as abuse.

@kevinansfield kevinansfield force-pushed the api-key/authentication branch 3 times, most recently from 35284af to 2cd5738 Compare October 3, 2018 12:39
@kevinansfield kevinansfield changed the title [WIP] Added API Key authentication middleware to v2 API routes Added API Key authentication middleware to v2 API routes Oct 3, 2018
@kevinansfield
Copy link
Contributor Author

@kirrg001 ready for review

},

// ### v2 API auth middleware
rejectAdminApiKey: apiKeyAuth.admin.rejectAdminApiKey,

This comment was marked as abuse.

// ### v2 API auth middleware
rejectAdminApiKey: apiKeyAuth.admin.rejectAdminApiKey,
authenticateAdminApiKey: apiKeyAuth.admin.authenticateAdminApiKey,
rejectContentApiKey: apiKeyAuth.content.rejectContentApiKey,

This comment was marked as abuse.

@@ -0,0 +1,212 @@
const {
authenticateAdminApiKey,
rejectAdminApiKey

This comment was marked as abuse.

const common = require('../../../../../server/lib/common');
const {
authenticateContentApiKey,
rejectContentApiKey

This comment was marked as abuse.

Copy link
Contributor

@allouis allouis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks solid - just those few things need removing

@kevinansfield
Copy link
Contributor Author

Fixed up the poor global-find-delete job when removing the rejectX middleware 😬

@allouis
Copy link
Contributor

allouis commented Oct 4, 2018

:D looks good to me

@kevinansfield kevinansfield changed the title Added API Key authentication middleware to v2 API routes [WIP] Added API Key authentication middleware to v2 API routes Oct 8, 2018
@allouis allouis changed the title [WIP] Added API Key authentication middleware to v2 API routes Added API Key authentication middleware to v2 API routes Oct 8, 2018
@allouis
Copy link
Contributor

allouis commented Oct 8, 2018

@kevinansfield This needs a rebase
@kirrg001 Would you mind taking a look at this when you can?

@@ -100,7 +101,10 @@ const authenticate = {
)(req, res, next);
},

authenticateAdminAPI: [session.safeGetSession, session.getUser]
// ### v2 API auth middleware
authenticateAdminAPI: [session.safeGetSession, session.getUser],

This comment was marked as abuse.

@@ -37,7 +37,17 @@ const authorize = {
};
},

authorizeAdminAPI: [session.ensureUser]
authorizeAdminAPI: [session.ensureUser],

This comment was marked as abuse.

@allouis
Copy link
Contributor

allouis commented Oct 8, 2018

This now breaks a test - will add a separate commit for that

kevinansfield and others added 2 commits October 8, 2018 18:42
refs TryGhost#9865
- add `auth.authenticate.authenticateAdminApiKey` middleware
  - accepts signed JWT in an `Authorization: Ghost [token]` header
  - sets `req.api_key` if the token is valid
- add `auth.authenticate.authenticateContentApiKey` middleware
  - accepts `?content_key=` query param, sets `req.api_key` if it's a known Content API key
- add `requiresAuthorizedUserOrApiKey` authorization middleware
  - passes if either `req.user` or `req.api_key` exists
- update `authenticatePrivate` middleware stack for v2 admin routes
- update `authenticatePublic` middleware stack for v2 content routes
no-issue

This can be reimplemented once we have auth helpers for the content API
tests.
@allouis allouis added p1:priority [triage] Priority for immediate patch release priority and removed p1:priority [triage] Priority for immediate patch release labels Oct 12, 2018
auth.authenticate.authenticateClient,
auth.authenticate.authenticateUser,
// This is a labs-enabled middleware
auth.authorize.requiresAuthorizedUserPublicAPI,

This comment was marked as abuse.

This comment was marked as abuse.

This comment was marked as abuse.

This comment was marked as abuse.

"unknownAdminApiKey": "Unknown Admin API Key",
"unknownContentApiKey": "Unknown Content API Key",
"invalidApiKeyType": "Invalid API Key type",
"invalidJwt": "Invalid JWT",

This comment was marked as abuse.

This comment was marked as abuse.

This comment was marked as abuse.

* - the "Audience" claim should match the requested API path
* https://tools.ietf.org/html/rfc7519#section-4.1.3
*/
const authenticateAdminApiKey = function authenticateAdminApiKey(req, res, next) {

This comment was marked as abuse.

This comment was marked as abuse.

This comment was marked as abuse.

This comment was marked as abuse.

@@ -77,7 +77,8 @@ describe('Public API', function () {
});
});

it('browse pages', function (done) {
// TODO: move to v2 folder, and don't skip once we have auth helper for content api tests
it.skip('browse pages', function (done) {

This comment was marked as abuse.

This comment was marked as abuse.

This comment was marked as abuse.

@allouis
Copy link
Contributor

allouis commented Oct 13, 2018

Due to splitting and not wanting to mess with kevins branch too much i've made a new PR #10005 with the content api changes and #10006 with the admin api changes ☺️

@kirrg001
Copy link
Contributor

Due to splitting and not wanting to mess with kevins branch too much i've made a new PR #10005 with the content api changes and #10006 with the admin api changes ☺️

👍

I think this one can be closed now 👍

@allouis allouis closed this Oct 15, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants