Closed james-mchugh closed 5 months ago
For anyone experiencing a similar issue, I was able to work around this in Apisix by utilizing the radixtree router. I created a variable-based router to utilize the openidc plugin with the relying party flow only if the request's user agent string includes tokens that typically appear in browsers (chrome, firefox, etc.). Otherwise, bearer only authentication is used. Below is an example configuration:
routes:
- uri: /frontend/*
plugins:
openid-connect:
client_id: "${{OIDC_CLIENT_ID}}"
client_secret: "${{OIDC_CLIENT_SECRET}}"
discovery: "${{OIDC_DISCOVERY_URL}}"
realm: "${{OIDC_REALM}}"
bearer_only: false
session:
secret: "${{OIDC_SESSION_SECRET}}"
service_id: 1
# For browsers, handle the session cookie at the route level.
- uri: /backend/*
vars:
- - "http_user_agent"
- "~*"
- "(chromium|chrome|firefox|safari|opr|opera|seamonkey)"
plugins:
openid-connect:
client_id: "${{OIDC_CLIENT_ID}}"
client_secret: "${{OIDC_CLIENT_SECRET}}"
discovery: "${{OIDC_DISCOVERY_URL}}"
realm: "${{OIDC_REALM}}"
unauth_action: deny
bearer_only: false
session:
secret: "${{OIDC_SESSION_SECRET}}"
service_id: 2
# For other clients, defer authentication to the service
- uri: /backend/*
service_id: 2
services:
- id: 1
upstream:
nodes:
"frontend:80": 1
- id: 2
upstream:
nodes:
"backend:80": 1
# Fall back to bearer only authentication to ensure all requests to the backend are authenticated
plugins:
openid-connect:
client_id: "${{OIDC_CLIENT_ID}}"
client_secret: "${{OIDC_CLIENT_SECRET}}"
discovery: "${{OIDC_DISCOVERY_URL}}"
realm: "${{OIDC_REALM}}"
bearer_only: true
I do still think it's worth considering ways in lua-resty-openidc to make this more straightforward.
After pouring over the lua-rest-openidc code and the Apisix plugin code for a little while, I realized this is probably more of a problem with the Apisix plugin code. Sorry for the confusion. I'll go ahead and close this
Environment
Expected behaviour
If
bearer_only=False
and an access token is passed in the Authorization header, the access token will be used if the cookie is not present.Actual behaviour
Access token in authorization header is ignored.
Minimized example
Apisix route config:
Configuration and NGINX server log files
Investigation
This appears to happen due to the
openidc_get_bearer_access_token
function checkingaccept_token_as
to see where it should source the token from (cookie or authorization header). If this is set to cookie, it automatically short circuits and attempts to pull the token from the cookie at https://github.com/zmartzone/lua-resty-openidc/blob/master/lib/resty/openidc.lua#L1637. There does not seem to be any fallback handling if the handling of the cookie fails.This may be intended behavior. The Apisix documentation seemed to indicate that the authorization header or cookie could be present if
bearer_only
is false, but it may be incorrect.Use Case
For my use case, I have a browser-based application and a "legacy" CLI-based application. They will both be accessing the same backend server through a gateway (Apisix), where your plugin is being used to enforce authentication. For the browser-based authentication, when the frontend server is accessed, the request goes through the Apisix route using the
lua-resty-openidc
plugin and receives a cookie upon successful authentication. This works great. The browser is then expected to send requests directly to the backend and include the cookie so Apisix and lua-resty-openidc can validate the requests are authenticated.For the CLI application, that will need to store the token locally and include that in the Authorization header to requests to the backend server. This is going through the same route as the browser's request to the backend server, as the hostname and URL path are the same. The expectation here was that the
lua-resty-openidc
plugin would still check the authorization header even ifbearer_only=false
, but that does not appear to be happening. Instead, I always get 401 responses from Apisix when trying to access these endpoints.Are there other ways of handling this that make more sense?