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

adds sha1 support for basic auth plugin (issue #33) #527

Closed
wants to merge 1 commit into from

Conversation

tyiss
Copy link

@tyiss tyiss commented Sep 2, 2015

Note: this code is not ready yet, just wanted to ask some questions related to it.

The code add support for sha1 passowrds.
it adds a configuration key 'encryption_method' that have the following values:

  • plain: plain passwords .
  • sha1: sha1 encrypted passwords. password salted with consumer id.

questions:

  1. in sha1 as mention in [basicauth] Encrypt password field #33, salt the sha1 with consumer id.
    i was wondering how it to test: is there a way the i could set consumer id, so that i could test the return sha1 (i could not find one) ?
  2. tests: i have diffrent plugin configuration to test. plain passwords, sha1 passwords.
    how can i add and use different configuration for a plugin? should i find a way to remove plugin conf ?
  3. what is the preferred way to get plugin configuration in access phase ?

@thibaultcha thibaultcha added the pr/wip A work in progress PR opened to receive feedback label Sep 4, 2015
local basic_auth_utils = require "kong.plugins.basic-auth.utils"

local function get_config(dao_factory)
-- in case of no conf.
Copy link
Member

Choose a reason for hiding this comment

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

this is not possible, config is mandatory.

@thibaultcha
Copy link
Member

i was wondering how it to test: is there a way the i could set consumer id, so that i could test the return sha1 (i could not find one) ?

You can retrieve a consumer id before creating an encrypted credential.

tests: i have diffrent plugin configuration to test. plain passwords, sha1 passwords.
how can i add and use different configuration for a plugin? should i find a way to remove plugin conf ?

Use different APIs and apply one plugin config on each (with insert_fixtures), or 1 API and 1 plugin and update it with the DAO.

what is the preferred way to get plugin configuration in access phase ?

In the access phase the plugin config is given as a parameter of the :access() function

@thibaultcha
Copy link
Member

Where is the part for the 8000 port? Now that it is encrypted, consumers still set their password in plain in their requests, and it needs to be compared with the digest during the proxy part.

encryption_method = "plain",
}

local data, err = dao_factory.plugins:find_by_keys({ name = "basic-auth" })
Copy link
Member

Choose a reason for hiding this comment

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

I am just realising now but... This is retrieving any configuration? That won't do it. We need to update the core to introduce some kind of link between a plugin configuration and related entities (such as credentials) created by plugins.

Copy link
Author

Choose a reason for hiding this comment

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

exactly, i was hitting that wall, (this code just retrive the first plugin conf) wanted someone that knows the internals to advice.
currently there is only one encryption method (plain).
i thought it will be more flexible to have encryption method along side others, so that, we can be smoothly backward compatible, and a consumer/api (not sure what entity) could have different encryption methods.

do you see how this link could be achieved ?

@tyiss
Copy link
Author

tyiss commented Sep 7, 2015

that port 8000 code is indeed missing.

here is the patch (i don't update the PR cause there will be other changes- reflected by you're review).

 local constants = require "kong.constants"
+local basic_auth_utils = require "kong.plugins.basic-auth.utils"
 local AUTHORIZATION = "authorization"
 local PROXY_AUTHORIZATION = "proxy-authorization"
@@ -57,11 +58,14 @@ end
 -- @param {table} credential The retrieved credential from the username
passed in the request
 -- @param {string} username
 -- @param {string} password
+-- @param {table} conf
 -- @return {boolean} Success of authentication
-local function validate_credentials(credential, username, password)
+local function validate_credentials(credential, username, password, conf)
   if credential then
-    -- TODO: No encryption yet
-    return credential.password == password
+    local method = conf.encryption_method or "plain"
+    local transform_function = basic_auth_utils.encryption_methods[method]
or encryption_methods.plain
+    local consumer = {password = password, consumer_id =
credential.consumer_id}
+    return transform_function(consumer) == credential.password

@@ -0,0 +1,40 @@
local resty_string = require "resty.string"
local resty_sha1 = require "resty.sha1"
Copy link
Member

Choose a reason for hiding this comment

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

There is actually an issue with this. Since we want the encryption to happen at the DAO level, this will be included in the DAO's schema. However, when running unit tests, resty.string cannot be required since it is not a module installed by Luarocks, but only available inside of Openresty... It prevents from running unit tests against it but more important, it breaks the basicauth_credentials DAO in the unit tests... I am not sure what to do about it. We could either use another module for the encryption or try to mock it somehow.

Copy link
Author

Choose a reason for hiding this comment

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

Correct, there is no way to unit test inside functionality, which include - Openresty modules.
imho, in addition to the current test suite, we need new test suite that could test inside modules. maybe we could use resty-cli for this.
for this particular case, i can include self-contained sha1 lib (or lua rock), so that i will not require resty module.

if this should be at the DAO level (how cassandra specific?), when we add support for other databases, any plugin will need to have its own sha1 (and upcoming encryption) implementations ?

@thibaultcha
Copy link
Member

See #533

thibaultcha added a commit that referenced this pull request Sep 10, 2015
On the contrary of #527, this only allows for sha1 encryption. The
reason is that due to the current architecture, we cannot support two
types at the same time (supporting plain is a bad practice anyways).
Because a basicauth_credential has no relation to a plugin entity (they
are **not** semantically related anyways), we cannot now how the
password is stored/encrypted.

I also took the opportunity of 0.5.0 and the migration script to make
that decision. The migration script will be updated to also migrate the
current passwords.

This does a bit more than #527:

- unit tests
- support encryption in unit test mode (with a mock using a vendor sha1
  library)
- comparison of the hash at the proxy level (for actual authentication)

Resolves #33
@thibaultcha
Copy link
Member

Closing this in favour of #533 (which now needs review) thanks!

thibaultcha added a commit that referenced this pull request Sep 15, 2015
On the contrary of #527, this only allows for sha1 encryption. The
reason is that due to the current architecture, we cannot support two
types at the same time (supporting plain is a bad practice anyways).
Because a basicauth_credential has no relation to a plugin entity (they
are **not** semantically related anyways), we cannot now how the
password is stored/encrypted.

I also took the opportunity of 0.5.0 and the migration script to make
that decision. The migration script will be updated to also migrate the
current passwords.

This does a bit more than #527:

- unit tests
- support encryption in unit test mode (with a mock using a vendor sha1
  library)
- comparison of the hash at the proxy level (for actual authentication)

Resolves #33
thibaultcha added a commit that referenced this pull request Sep 21, 2015
On the contrary of #527, this only allows for sha1 encryption. The
reason is that due to the current architecture, we cannot support two
types at the same time (supporting plain is a bad practice anyways).
Because a basicauth_credential has no relation to a plugin entity (they
are **not** semantically related anyways), we cannot now how the
password is stored/encrypted.

I also took the opportunity of 0.5.0 and the migration script to make
that decision. The migration script will be updated to also migrate the
current passwords.

This does a bit more than #527:

- unit tests
- support encryption in unit test mode (with a mock using a vendor sha1
  library)
- comparison of the hash at the proxy level (for actual authentication)

Resolves #33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pr/wip A work in progress PR opened to receive feedback
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants