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

feat(plugin-jwt) support RS512 algorithm for signing tokens. #2642

Closed
wants to merge 51 commits into from

Conversation

sarraz1
Copy link
Contributor

@sarraz1 sarraz1 commented Jun 20, 2017

Add support of RS512 algorithm for signing tokens in jwt plugin.

This add-on is based on the already-used module "crypto".

Tieske and others added 30 commits March 27, 2017 21:57
We now avoid reading all request headers via `ngx.req.get_headers()` and
use the `ngx.var` API instead. In the future, we'll distinguish Host
fetching and full headers fetching when arbitrary headers matching will
be added to the router.
When we don't route an API via its `hosts` property (no Host recorded),
this test ensures that we still forward the incoming request `Host`
header when `preserve_host = true`.
…without-hosts

tests(router) ensure preserve_host without hosts matching
…ding

perf(router) efficient host header reading
ngx.time uses a cached time struct that obviates the need for the
syscall performed by os.time. additionally, os.time is not JITable.
perf(aws-lambda) use ngx.time in place of os.time
Signed-off-by: Wei.ZHAO <zhaowei@qiyi.com>
fix(test) remove the redundant right parentheses
Signed-off-by: Wei.ZHAO <zhaowei@qiyi.com>
fix(conf) set `nobody nobody` as default nginx user
Right now we suggest compiling LuaJIT with `--without-luajit-lua52`.
All the official OpenResty packages compile LuaJIT with Lua 5.2
compatibility, and we should follow the suit.

Also it looks like some of the tests were using `os.execute("sleep ...")`
instead of `ngx.sleep(...)` for legacy reasons. This pull-request fixes
that as well.

From Kong#2296
Add two new configuration properties `server_tokens` and
`latency_tokens` to toggle `Server` and `X-Kong-*-Latency` response
headers.

From Kong#2259
Fix Kong#1009
We can set the `ctx` value in a single places for both branches where it
is required for it to be `true`.

Signed-off-by: Thibault Charbonnier <thibaultcha@me.com>
The `user` directive only makes sense if the master process
runs with super-user privileges.

From Kong#2321
* Add real_ip_recursive and set_real_ip_from Kong configuration fields to
configure ngx_http_realip_module directives.
* Move the real_ip directives to the Kong proxy location block.
* Add configuration building unit tests for those 2 new directives.

Fix Kong#1661
Deprecates Kong#1662
* Introduce trusted_ips config property
* Introduce real_ip_header
* New lua-resty-mediador
* Implement logic to validate client ips as trusted
* Implement Lua logic for the X-Forwarded-For upstream header
* Move the WebSocket upstream headers dance to the Lua-land instead of
  the old Nginx maps.
* Related tests (renamed real_ip test suite to upstream_headers)

Fix Kong#2202
When `real_ip_header = proxy_protocol`, we enable the PROXY protocol
support on the Nginx side, by appending the `proxy_procotol` option to
the `listen` directive of the proxy server.

Implement Kong#2240
Those parts of the configuration were erroneously removed during my
cleaning up of the git history from the X-Forwarded-* headers branch.
p0pr0ck5 and others added 17 commits April 25, 2017 16:56
The compound primary key, coupled with a lack of unique constraint
on id, allows for duplicate plugin UUIDs, breaking expected behavior.
This commit adds a unique constraint in the Kong schema, and directly
to the Postgres table definition via a migration.
In addition to BAD_REQUEST messages sent by Kong, we should also
handle natively-generated 400 response codes.
Extra care should have been given to a few CRUD helper methods after the
recent merge to 'master'. This fixes the behavior of a few routes in the
Admin API and takes both branches' recent changes into account
The recent .luacheckrc file disabled both unused args and unused
variables. We make sure to re-enable unused variables linting, and fix
all of the mistakes made in the meanwhile.
Installation methods such as homebrew/kong must use unusual rock trees
locations. Currently, this patch is shipped with it since
Kong/homebrew-kong#43
This commit provides an optional plugin configuration field to
search the request body for the authentication credentials. This
behavior respects the hide_credentials field.

This commit also expands the access test suite to cover a few more
use cases.
Follow-up from the previous merge from master which re-introduces
linting for unused variables.
The current implementation of utils.random_string() leverages
the LuaJIT math.random() under the hood to generate bytes; this is
unsuitable for cases where cryptographically secure random data
is needed, such as fallback values for authentication plugin
secret values. To correct this, we introduce a wrapper around
the kernel CSPRNG (via /dev/urandom) to read random bytes, and
wrap utils.random_string around this. We also return these bytes
in a modified Base64 encoding (replacing non-alphanumeric characters
with random alphanumeric replacements); this serves to increase
the size of the keyspace significantly while attempting to
maintain some backwards compatibility with previous generated string
parameters (e.g. by generating a string of the same size and a
somewhat matching pattern).

The underlying get_rand_bytes implementation is modified to read
from /dev/urandom when explicitly requested, and falling back to
OpenSSL's RAND_bytes when reading from urandom fails. The blocking
read from urandom is acceptable when explicitly requested, as this
is typically done in asynchronous environments (e.g. admin API
requests), where the need for strong psuedorandomness outweighs
the overhead of I/O and talking to the kernel.
additionally makes some more options configurable
Add support of RS512 algorithm for signing tokens.
Copy link
Contributor

@p0pr0ck5 p0pr0ck5 left a comment

Choose a reason for hiding this comment

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

Thank you for the submission! Overall looks good, mostly minor style/cleanup comments. Also, as this does not appear to be a breaking change, it can probably be merged against master instead of next. Thank you!

@@ -10,9 +10,9 @@ local SCHEMA = {
created_at = {type = "timestamp", immutable = true, dao_insert_value = true},
consumer_id = {type = "id", required = true, foreign = "consumers:id"},
key = {type = "string", unique = true, default = utils.random_string},
secret = {type = "string", default = utils.random_string},
secret = {type = "string", unique = true, default = utils.random_string},
Copy link
Contributor

Choose a reason for hiding this comment

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

This seems like an undesirable change? It was recently removed, and I'm not sure I see a reason here for it to be added in?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

there is no reason.

assert.False(jwt:verify_signature(fixtures.rs512_public_key:gsub('AE=', 'zzz')))
end)
-- it("test", function()
--assert.True(TRUE)
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's remove this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok

it("verifies JWT", function()
PAYLOAD.iss = rsa_jwt_secret_3.key
local jwt = jwt_encoder.encode(PAYLOAD, fixtures.rs512_private_key, 'RS512')
local authorization = "Bearer "..jwt
Copy link
Contributor

Choose a reason for hiding this comment

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

Style: spaces around the string concat operator

it("identifies Consumer", function()
PAYLOAD.iss = rsa_jwt_secret_3.key
local jwt = jwt_encoder.encode(PAYLOAD, fixtures.rs512_private_key, 'RS512')
local authorization = "Bearer "..jwt
Copy link
Contributor

Choose a reason for hiding this comment

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

Style: spaces around the string concat operator

@@ -21,6 +21,12 @@ local SCHEMA = {
if plugin_t.algorithm == "RS256" and crypto.pkey.from_pem(plugin_t.rsa_public_key) == nil then
return false, Errors.schema "'rsa_public_key' format is invalid"
end
if plugin_t.algorithm == "RS512" and plugin_t.rsa_public_key == nil then
return false, Errors.schema "no mandatory 'rsa_public_key'"
Copy link
Contributor

Choose a reason for hiding this comment

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

Seems we're indenting by four spaces here, instead of two? Can we align this with the rest of the block?

@@ -49,6 +50,10 @@ local alg_verify = {
local pkey = assert(crypto.pkey.from_pem(key), "Consumer Public Key is Invalid")
return crypto.verify('sha256', data, signature, pkey)
end,
["RS512"] = function(data, signature, key)
local pkey = assert(crypto.pkey.from_pem(key), "Consumer Public Key is Invalid")
Copy link
Contributor

Choose a reason for hiding this comment

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

please check indentation spacing here as well.

it("accepts a valid RS512 encoding request", function()
local token = jwt_parser.encode({sub = "1234"}, "secret", nil, {
typ = "JWT",
alg = "RS512"
Copy link
Contributor

Choose a reason for hiding this comment

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

minor style nitpick, its preferred to leave a trailing comma after the last item in a table to facilitate cleaner future commit histories.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

so:
alg = "RS512",

it("accepts a valid RS512 encoding request with lowercase TYP", function()
local token = jwt_parser.encode({sub = "1234"}, "secret", nil, {
typ = "jwt",
alg = "RS512"
Copy link
Contributor

Choose a reason for hiding this comment

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

same as above.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes

path = "/request",
headers = {
["Authorization"] = authorization,
["Host"] = "jwt.com"
Copy link
Contributor

Choose a reason for hiding this comment

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

trailing coma here

path = "/request",
headers = {
["Authorization"] = authorization,
["Host"] = "jwt.com"
Copy link
Contributor

Choose a reason for hiding this comment

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

trailing coma here

@p0pr0ck5 p0pr0ck5 added pr/changes requested Changes were requested to this PR by a maintainer. Please address them and ping back once done. and removed pr/status/please review labels Jun 21, 2017
@p0pr0ck5
Copy link
Contributor

@sarraz1 any update based on the comments above?

@sarraz1
Copy link
Contributor Author

sarraz1 commented Jun 30, 2017 via email

@sarraz1 sarraz1 changed the base branch from next to master July 3, 2017 20:33
@sarraz1 sarraz1 changed the base branch from master to next July 3, 2017 20:34
@sarraz1 sarraz1 changed the base branch from next to master July 3, 2017 20:35
@sarraz1 sarraz1 mentioned this pull request Jul 3, 2017
@sarraz1
Copy link
Contributor Author

sarraz1 commented Jul 3, 2017

Like you suggested, I submitted a new PR from master: #2666
So you can cancel this one.

Regards

@thibaultcha
Copy link
Member

Closing as this is replaced by the new PR.

@thibaultcha thibaultcha closed this Jul 4, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pr/changes requested Changes were requested to this PR by a maintainer. Please address them and ping back once done.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants