zmartzone / lua-resty-openidc

OpenID Connect Relying Party and OAuth 2.0 Resource Server implementation in Lua for NGINX / OpenResty
Apache License 2.0
976 stars 248 forks source link

PKCE auth flow with token endpoint auth method = 'none' is not supported #530

Open ojathelonius opened 1 week ago

ojathelonius commented 1 week ago

It appears that none is the recommended configuration when using the PKCE auth flow for public clients (see OIDC 1.0 specs, Okta docs, Hydra docs). Is there a reason why this is not supported by the library? If not, is there a chance this is a minor change I could contribute to?

Environment
Expected behaviour

Using token_endpoint_auth_method="none" is supported when using use_pkce=true, enabling authorization code grant flow with PKCE for public clients that do not have a client_secret

Actual behaviour

The library does not support token_endpoint_auth_method="none" thus defaults to using basic auth which obviously fails for public clients due to the lack of client_secret

openidc.lua:662: openidc_get_token_auth_method(): configured value for token_endpoint_auth_method (none) is not supported, ignoring it
openidc.lua:684: openidc_get_token_auth_method(): 1 => client_secret_basic
Configuration and NGINX server log files

Sample nginx config

access_by_lua_block {
  local openidc = require("resty.openidc")
  local opts = {
     discovery = "https://some-website/.well-known/openid-configuration",
     client_id="abcdef",
     ssl_verify = "no",
     token_endpoint_auth_method = "none",
     redirect_uri_path = "/implicit/callback",
     use_pkce = true,
  }
  local res, err = openidc.authenticate(opts)
}
bodewig commented 1 week ago

The library never is a public client, it always is a trusted client with a client secret. so there is no reason to support the none algorithm as it would be way less secure than any of the supported alternatives.

ojathelonius commented 1 week ago

I don't follow why none is considered as less secure, as long as it is using PKCE. Unauthorized clients cannot generate tokens due to the authorization code flow. Why does the library require authentication for token generation when the OIDC specs do not?

oldium commented 1 week ago

I don't follow why none is considered as less secure, as long as it is using PKCE. Unauthorized clients cannot generate tokens due to the authorization code flow. Why does the library require authentication for token generation when the OIDC specs do not?

The PKCE does not serve as a way to authenticate clients. It only means that the client, which made the authorization endpoint request, is the one accessing the token endpoint. There is no client authentication, which is represented by value "none" actually.

bodewig commented 1 week ago

What @oldium says. lua-resty-openidc is not really a library, it is a client running inside an environment that is able to keep secrets, so there really is no need to not use a proper way to authenticate the client itself.

ojathelonius commented 1 week ago

Thank you for the explanation!

there really is no need to not use a proper way to authenticate the client itself.

I believe there are some cases where you would want to protect a resource using a public client, which OIDC supports. I understand that you recommend using a client that has secrets, but this is not always possible. This use case seems to be confirmed by the same feature request in oauth2-proxy. Is there then a strong case for not enabling this flow?

bodewig commented 1 week ago

At least I don't see why it would "not be possible" to use a secret for a client that is a server based application - which lua-resty-openidc is. Again "at least I" wouldn't want to encourage a configuration that is less secure.