-
-
Notifications
You must be signed in to change notification settings - Fork 797
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
Custom Authentication Plugin #1314
Conversation
Added the ability to inject a custom authentication strategy using a Serverless plugin
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you @tom-stclair
It looks very promising. Please see my comments
@pgrzesik what do you think of this addition?
removing package-lock.json
@medikoo, Regarding version number changes to the package.json and CHANGELOG.md made by contributors, what if I added a statement in the CONTRIBUTING.md with a statement that indicates that these changes shouldn't be included in PRs? |
It's a great idea. Still let's propose it with different PR |
@medikoo https://docs.npmjs.com/cli/v8/configuring-npm/package-lock-json
|
@xr0master I'm aware of this note. Still in case of this library, keeping this file is just about extra maintenance friction. with no real value added. Note it doesn't play any role for plugin users, and when maintenance is concerned we prefer the plugin to be tested in a similar environment in which it's actually used. For that, we intentionally ensure all deps are installed at the latest version to CI, so eventual regressions as caused by dependencies are detected early (with |
@medikoo Curiously, in this case, you're right. So, all dependencies must also have a caret ( |
Sorry @tom-stclair and @medikoo for not responding sooner, I've missed previous mention. I think this definitely sounds interesting, not sure how much people would be interested in using this functionality, but I don't see a reason as to why we shouldn't accept it. Just of curiosity @tom-stclair - is custom auth the only way to achieve it in your case? Maybe the plugin is missing a certain authentication strategy that should be just implemented directly in the plugin? |
@pgrzesik The custom authentication plugin we are looking to inject with this change allows us to declare the desired normalized claims that are provided to the invoked functions and greatly simplifies our ability to test and validate our software. It seemed reasonable that others using this project will have special authentication needs and rather than trying to update the project to satisfy every case a better approach was to allow this aspect to be extensible using the plugin framework of the broader serverless package. I see this change as having the potential to relieve pressure off of the maintainers of this project while also enabling consumers to move forward more rapidly. Please let me know if you think we are overlooking any existing functionality or you want more detail on our specific use case touched on above. |
Thanks for clarification @tom-stclair - that makes sense, @medikoo do you think we should move forward with this? I think we can have that in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pgrzesik thanks for feedback
@tom-stclair we're definitely fine to go with it, but I see one potential issue with proposed approach, please see my comment
}, | ||
} | ||
|
||
this.options.plugins = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doing that will change globally options
object for all plugins and serverless internals.
Any modifications to it are already coined as an anti-pattern: serverless/serverless#2582
It would be nicer to attach this configuration not via plugin, but simply via external module, something close to:
serverless.yml
custom:
offline:
customAuthorizationStrategy: ./authorization-strategy.js
authorization-strategy.js
module.exports = (endpoint, functionKey, method, path) => {
...
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@medikoo Thanks for the advice and apologies for the late reply. I believe I understand your suggestion, I need a bit of time to look into how serverless custom attributes are managed and how to inject the desired behavior from an external package.
Time has gone by quickly since your last reply and I wanted you to know that the intention is still to follow through with the suggested changes. It will be a few more days before I get a chance to get this updated.
Thanks again
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great thanks @tom-stclair for heads up. No worries, we look forward the update!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@medikoo - had a chance to make the suggested changes. Let me know if you had something else in mind.
Updated the way custom authentication can be injected. Moved from a serverless plugin to a custom variable in the serverless.yml 'offline.customAuthenticationProvider'
src/events/http/HttpServer.js
Outdated
customizations.offline?.customAuthenticationProvider | ||
) { | ||
// eslint-disable-next-line import/no-dynamic-require, global-require | ||
const provider = require(customizations.offline |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@medikoo - Based on your earlier feedback on moving this away from a serverless plugin, let me know if you see a better way to inject this. My desire would be that in serverless.yml you'd be able to add just a regular import statement in
custom: offline: customAuthenticationProvider:
this makes for an inline 'require', unless you know of a better way?
src/events/http/HttpServer.js
Outdated
customizations.offline?.customAuthenticationProvider | ||
) { | ||
// eslint-disable-next-line import/no-dynamic-require, global-require | ||
const provider = require(customizations.offline |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This require
will search in context of a directory in which this HttpServer.js
file is placed. While ideally we should search against service directory (it's also how we load service local plugins).
For that you can rely on https://nodejs.org/api/module.html#modulecreaterequirefilename, as we do indirectly in Framework here: https://github.com/serverless/serverless/blob/480d74ec58c78466d2d055e5c2d73c2f4dde0b42/lib/classes/plugin-manager.js#L159
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@medikoo - thanks for the feedback. I knew that the search would be relative to the HttpServer and wasn't thrilled with the confusion this could create but I didn't know this could be modified via createRequire.
I think this matches your suggestions, let me know if it doesn't.
moved from require() to createRequire() for custom authentication provider imports. This provides a more intuitive root directory for relative imports from the custom variables.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you @tom-stclair ! Looks good to me. Great improvement
@tom-stclair can you rebase against master? |
@medikoo - brought current with master |
@tom-stclair it's still marked as conflicting |
Added the ability to inject a custom authentication strategy using custom variables in the serverless definition, see README.md for more details.
removing package-lock.json
Updated the way custom authentication can be injected. Moved from a serverless plugin to a custom variable in the serverless.yml 'offline.customAuthenticationProvider'
moved from require() to createRequire() for custom authentication provider imports. This provides a more intuitive root directory for relative imports from the custom variables.
…serverless-offline into auth-plugin-support
@medikoo - I rebased with master, do you still see conflicts? |
@tom-stclair GitHub still reports as below, still I see I can merge it via squash'ing, I'll do it then |
@medikoo - that is excellent news about squash and merge, this seems to be a much simpler approach and I apprecienate it. Thanks for everything. |
@medikoo - What does the release schedule look like for this project, wondering when I can expect to see a new NPM package with this change? Thanks |
Hey @tom-stclair - I will prepare a release tomorrow |
Description
Added the ability to inject a custom authentication strategy using a Serverless plugin
Motivation and Context
I have the need for an authentication strategy that isn't satisfied by the existing capabilities of the project. This strategy is also very specific and not useful as a strategy to include in the project itself. This change allows the underlying authentication strategy used by the HttpServer.js to be defined in an external Serverless plugin.
How Has This Been Tested?
A new integration test has been added to the project that verifies that the authentication can be injected through a plugin.
All tests for the project have been run via the existing npm run test.
This branch has also been tested locally by incorporating it into existing projects that depend on the Serverless offline project.
Screenshots (if appropriate):