Closed jmdacruz closed 8 years ago
Is there documentation on the semantics of ngx.ctx.authenticated_credential.* and how the upstream plugins rely on the values there? What are the general rules on what to store there?
Unfortunately this is not documented. ngx.ctx.authenticated_credential
is usually a table that has the following properties:
ngx.ctx.authenticated_credential = {
id = "something",
consumer_id = "something"
}
How do ngx.ctx.authenticated_credential.consumer_id and ngx.ctx.authenticated_credential.id relate to each other?
ngx.ctx.authenticated_credential.id
is the ID of the actual credential entity on the database, while ngx.ctx.authenticated_credential.consumer_id
is the consumer whose the credential belongs to.
Can plugins that rely on some sort of customer ID survive with ngx.ctx.authenticated_credential.id or ngx.ctx.authenticated_credential.consumer_id not being an actual "Consumer ID" on the database?
I believe so.
The internal API is subject to change and we hope to freeze and document it in a 1.0 release, this is mainly the reason why things are a little bit vague right now. We are basically waiting for 1.0.
Thanks for the clarification, @thefosk. I think that leaving it open for these type of applications where consumers do not necessarily have an entity on the database makes a lot of sense. In some cases, certain plugins will work with this model (rate limiting being a clear example), but some other plugins might not (plugins that need to attach information to consumers beforehand). Plugins such as mine should be smart enough to try and look up a consumer on the database, and fall back to a entity-less consumer if none exists.
This means that the documentation for this situation it's just a set of "best practices" for plugin developers (which you inadvertently, or not, applied when developing the rate limiting plugin), e.g., treat IDs as opaque identifiers when possible, do not loop up an identifier on the database if not needed, etc.
Closing this question, we keep those things in mind in our roadmap.
The plugin is smart enough to check whether a Consumer exists for the token (it looks up the database matching "Custom ID" to the value coming on the token)
Hi @jmdacruz , how did you do this part? I can't see how to connect to my Postgres DB and e.g. lookup a user or a session/permissions. Did you write a custom Kong plugin?
@mecampbellsoup At the time (this was version 0.8.3 of Kong, if my memory serves me well), this was a custom plugin that would check against the Kong DB to try and get any available information for the consumer. The code for looking up the consumer data was something like this: https://github.com/Kong/kong/blob/0.8.3/kong/plugins/basic-auth/access.lua#L108. This was an optional step meant to provide extra info for the consumer (if present). Also note this was pre-PDK days, so you'll need to check the latest and greatest PDK.
I'm not sure if this is really an issue, but more of a general question and may be it's related to missing documentation.
I have a plugin that validates JWT tokens against an external service (an RFC 7662 token introspection endpoint), and passes certain parameters to the upstream service, such as attributes on the JWT. Because of the nature of our application, we can't have consumers pre-provisioned, and these type of tokens play nicely with that model since you basically get a "Consumer Custom ID" out of the token itself that the upstream service can use.
The plugin is smart enough to check whether a Consumer exists for the token (it looks up the database matching "Custom ID" to the value coming on the token), and if one exists then the "X-Consumer-ID" header is set. Else, only the "X-Consumer-Custom-ID" header is set with the value from the token.
I started to wonder about integration with other plugins, such as Rate Limiting. I see that many of these plugins rely on
ngx.ctx.authenticated_credential
being set, in most cases more specificallyngx.ctx.authenticated_credential.id
. From what I can gather from the code itself (looking at this: https://github.com/Mashape/kong/blob/0.8.1/kong/plugins/rate-limiting/handler.lua), I could in theory just setngx.ctx.authenticated_credential.id
to whatever I want and the plugin may just work (to avoid the plugin relying onngx.var.remote_addr
and being more accurate)Now, I understand that
ngx.ctx.authenticated_credential
may have some other properties, such asngx.ctx.authenticated_credential.consumer_id
. As I explained below, in most cases I won't have that value available in my plugin and I won't be able to set it in the context.So, I think the general requests/issues here are:
ngx.ctx.authenticated_credential.*
and how the upstream plugins rely on the values there? What are the general rules on what to store there?ngx.ctx.authenticated_credential.consumer_id
andngx.ctx.authenticated_credential.id
relate to each other?ngx.ctx.authenticated_credential.id
orngx.ctx.authenticated_credential.consumer_id
not being an actual "Consumer ID" on the database? The Rate Limiting plugin is clearly not looking the consumer on the database... but it could in theory do it, and that would break my assumption.I think the first bullet on the list above is they key, so that developers building authentication plugins clearly understand the rules of engagement. Maybe having a core function for the plugins to populate the context uniformly would help, so that the semantics are encoded there instead of every plugin relying on looking at other plugins' code.