Duplicate requests using decisions endpoint via NGINX
karlis-vagalis opened this issue · 0 comments
Preflight checklist
- I could not find a solution in the existing issues, docs, nor discussions.
- I agree to follow this project's Code of Conduct.
- I have read and am following this repository's Contribution Guidelines.
- I have joined the Ory Community Slack.
- I am signed up to the Ory Security Patch Newsletter.
Ory Network Project
No response
Describe the bug
I am facing an issue using Oathkeeper's Access Control Decision API.
It is being used as for Nginx via Authentication Based on Subrequest Result. Most of the logic works well and correctly, user is being redirected to the authentication page (based on the rule), can log in, is redirected back to the page, but then the issue starts. For example, requesting test.mydomain.com
should check authentication from Ory Kratos (v1.1.0) or redirect to auth page at auth.mydomain.com
and then allow accessing the site.
As Oathkeepers logs indicate, for whatever reason the /decisions
request seems to be duplicated. The first request indicates, that the access to the url is granted (200, OK), but afterwards (no idea why), follows a send request with same headers, but that one is being responded with 404, Not Found, even though the URI is same. I thought I made an error in my rule definition, but why would the next request fail then, if the first did match?
The configuration files are attached below.
Config files
Oathkeeper Rules
rules.yml
:
- id: "mydomain:subdomains:private"
match:
url: "<http|https>://<[^.]+>.mydomain.com<(.*)?>"
methods:
- GET
- POST
- PUT
- DELETE
- PATCH
authenticators:
- handler: cookie_session
authorizer:
handler: allow
mutators:
- handler: noop
NGINX
server {
listen 443 ssl http2 proxy_protocol;
listen [::]:443 ssl http2 proxy_protocol;
server_name test.mydomain.com;
include /config/nginx/ssl.conf;
client_max_body_size 0;
include /config/nginx/ory-server.conf;
location / {
include /config/nginx/ory-location.conf;
include /config/nginx/proxy.conf;
include /config/nginx/resolver.conf;
set $upstream_app test;
set $upstream_port 80;
set $upstream_proto http;
proxy_pass $upstream_proto://$upstream_app:$upstream_port;
}
}
ory-server.conf
:
# Location for Ory Oathkeeper authentication requests
location = /decisions {
internal;
include /config/nginx/proxy.conf;
include /config/nginx/resolver.conf;
set $upstream_proto http;
set $upstream_app oathkeeper;
set $upstream_port 4456;
proxy_pass $upstream_proto://$upstream_app:$upstream_port;
## Include the Set-Cookie header if present
auth_request_set $set_cookie $upstream_http_set_cookie;
add_header Set-Cookie $set_cookie;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
}
# Virtual location for Ory Oathkeeper authentication redirects
location @ory_proxy_signin {
internal;
## Include the Set-Cookie header if present
auth_request_set $set_cookie $upstream_http_set_cookie;
add_header Set-Cookie $set_cookie;
## Set the $target_url variable based on the original request
set_escape_uri $target_url $scheme://$http_host$request_uri;
## Translate the Location response header from the auth subrequest into a variable
auth_request_set $signin_url $upstream_http_location;
if ($signin_url = '') {
## Set the $signin_url variable
set $signin_url https://auth.mydomain.com/login?return_to=$target_url;
}
## Redirect to login
return 302 $signin_url;
}
ory-location.conf
:
auth_request /decisions;
## If the subreqest returns 200 pass to the backend, if the subrequest returns 401 redirect to the portal
error_page 401 = @ory_proxy_signin;
# ## Translate the user information response headers from the auth subrequest into variables
auth_request_set $email $upstream_http_remote_email;
auth_request_set $groups $upstream_http_remote_groups;
auth_request_set $name $upstream_http_remote_name;
auth_request_set $user $upstream_http_remote_user;
## Inject the user information into the request made to the actual upstream
proxy_set_header Remote-Email $email;
proxy_set_header Remote-Groups $groups;
proxy_set_header Remote-Name $name;
proxy_set_header Remote-User $user;
## Translate the Set-Cookie response header from the auth subrequest into a variable
auth_request_set $set_cookie $upstream_http_set_cookie;
## Translate the Location response header from the auth subrequest into a variable
auth_request_set $signin_url $upstream_http_location;
Reproducing the bug
- Have valid and working Ory Kratos instance.
- Start Oathkeeper with described configuration and rules
- Set up NGINX reverse proxy to use Ory Oathkeeper for
auth_request
to access server. - Try to access server.
Relevant log output
{"handling":"","level":"info","msg":"started","request":"","time":"2024-03-27T09:24:04Z"}
time=2024-03-27T09:24:04Z level=info msg=Access request granted audience=application granted=true http_host=test.mydomain.com http_method=GET http_url=https://test.mydomain.com/ http_user_agent=Mozilla/5.0 (X11; Linux x86_64; rv:124.0) Gecko/20100101 Firefox/124.0 service_name=ORY Oathkeeper service_version=v0.40.7
{"handling":"","level":"info","msg":"completed","request":"","time":"2024-03-27T09:24:04Z"}
{"handling":"","level":"info","msg":"started","request":"","time":"2024-03-27T09:24:04Z"}
{"handling":"","level":"info","msg":"completed","request":"","time":"2024-03-27T09:24:04Z"}
time=2024-03-27T09:24:04Z level=info msg=started handling request http_request=map[headers:map[accept:image/avif,image/webp,*/* accept-encoding:gzip, deflate, br accept-language:en-US,en;q=0.5 cache-control:no-cache connection:close cookie:[ory_kratos_session=MTcxMTUyOTQxNnx6Q0xpYnRYbE9jakxkM05LLWVMYS02Q1N5bnBnR1hZQmR3VTFRMTJaMWZneVZUR0hCU2RKa2VEaU5GZkJ5dWZJRkhPdGNKbmgwN3VDY0h2d0tDT3ZGUmhwWkFfMGlaRkVEdkNIVWhubmo5WHo5V0diSGJYdmZvd3RrUFRoVFIwNkNETGlfRHJmaE5mMWRVT283SFpGSlBGQ1pFYnVIN0FiSnpISnFiaHlUaHVKR0FjZkVGV0dQRkdRQU5zOUxocUxUMnZzbWRYOFB3a3gzSkJoUjJNbzR6QVJHa21uTjdDemktaWF5azhHME80Rm1qdDRiOFdrdU84Wi1GVmg1WVdnQmZnckVIRy02eWlZTW1TekxnQ2t8Y_TSiwcfeY5FN5_mi6wPFZqxjdXBlTzL2DyL5_Ot9gc=] dnt:1 pragma:no-cache referer:https://test.mydomain.com/ sec-fetch-dest:image sec-fetch-mode:no-cors sec-fetch-site:same-origin sec-gpc:1 user-agent:Mozilla/5.0 (X11; Linux x86_64; rv:124.0) Gecko/20100101 Firefox/124.0 x-forwarded-for:192.168.2.26 x-forwarded-host:test.mydomain.com x-forwarded-method:GET x-forwarded-port:443 x-forwarded-proto:https x-forwarded-server:test.mydomain.com x-forwarded-ssl:on x-forwarded-uri:/favicon.ico x-original-method:GET x-original-url:https://test.mydomain.com/favicon.ico x-real-ip:192.168.2.26] host:test.mydomain.com method:GET path:/decisions query:<nil> remote:[fd00:2::10]:56798 scheme:http]
time=2024-03-27T09:24:04Z level=info msg=Access request granted audience=application granted=true http_host=test.mydomain.com http_method=GET http_url=https://test.mydomain.com/favicon.ico http_user_agent=Mozilla/5.0 (X11; Linux x86_64; rv:124.0) Gecko/20100101 Firefox/124.0 service_name=ORY Oathkeeper service_version=v0.40.7
time=2024-03-27T09:24:04Z level=info msg=completed handling request http_request=map[headers:map[accept:image/avif,image/webp,*/* accept-encoding:gzip, deflate, br accept-language:en-US,en;q=0.5 cache-control:no-cache connection:close cookie:[ory_kratos_session=MTcxMTUyOTQxNnx6Q0xpYnRYbE9jakxkM05LLWVMYS02Q1N5bnBnR1hZQmR3VTFRMTJaMWZneVZUR0hCU2RKa2VEaU5GZkJ5dWZJRkhPdGNKbmgwN3VDY0h2d0tDT3ZGUmhwWkFfMGlaRkVEdkNIVWhubmo5WHo5V0diSGJYdmZvd3RrUFRoVFIwNkNETGlfRHJmaE5mMWRVT283SFpGSlBGQ1pFYnVIN0FiSnpISnFiaHlUaHVKR0FjZkVGV0dQRkdRQU5zOUxocUxUMnZzbWRYOFB3a3gzSkJoUjJNbzR6QVJHa21uTjdDemktaWF5azhHME80Rm1qdDRiOFdrdU84Wi1GVmg1WVdnQmZnckVIRy02eWlZTW1TekxnQ2t8Y_TSiwcfeY5FN5_mi6wPFZqxjdXBlTzL2DyL5_Ot9gc=] dnt:1 pragma:no-cache referer:https://test.mydomain.com/ sec-fetch-dest:image sec-fetch-mode:no-cors sec-fetch-site:same-origin sec-gpc:1 user-agent:Mozilla/5.0 (X11; Linux x86_64; rv:124.0) Gecko/20100101 Firefox/124.0 x-forwarded-for:192.168.2.26 x-forwarded-host:test.mydomain.com x-forwarded-method:GET x-forwarded-port:443 x-forwarded-proto:https x-forwarded-server:test.mydomain.com x-forwarded-ssl:on x-forwarded-uri:/favicon.ico x-original-method:GET x-original-url:https://test.mydomain.com/favicon.ico x-real-ip:192.168.2.26] host:test.mydomain.com method:GET path:/favicon.ico query:<nil> remote:[fd00:2::10]:56798 scheme:http] http_response=map[headers:map[accept:image/avif,image/webp,*/* accept-encoding:gzip, deflate, br accept-language:en-US,en;q=0.5 cache-control:no-cache connection:close cookie:[ory_kratos_session=MTcxMTUyOTQxNnx6Q0xpYnRYbE9jakxkM05LLWVMYS02Q1N5bnBnR1hZQmR3VTFRMTJaMWZneVZUR0hCU2RKa2VEaU5GZkJ5dWZJRkhPdGNKbmgwN3VDY0h2d0tDT3ZGUmhwWkFfMGlaRkVEdkNIVWhubmo5WHo5V0diSGJYdmZvd3RrUFRoVFIwNkNETGlfRHJmaE5mMWRVT283SFpGSlBGQ1pFYnVIN0FiSnpISnFiaHlUaHVKR0FjZkVGV0dQRkdRQU5zOUxocUxUMnZzbWRYOFB3a3gzSkJoUjJNbzR6QVJHa21uTjdDemktaWF5azhHME80Rm1qdDRiOFdrdU84Wi1GVmg1WVdnQmZnckVIRy02eWlZTW1TekxnQ2t8Y_TSiwcfeY5FN5_mi6wPFZqxjdXBlTzL2DyL5_Ot9gc=] dnt:1 pragma:no-cache referer:https://test.mydomain.com/ sec-fetch-dest:image sec-fetch-mode:no-cors sec-fetch-site:same-origin sec-gpc:1 user-agent:Mozilla/5.0 (X11; Linux x86_64; rv:124.0) Gecko/20100101 Firefox/124.0 x-forwarded-for:192.168.2.26 x-forwarded-host:test.mydomain.com x-forwarded-method:GET x-forwarded-port:443 x-forwarded-proto:https x-forwarded-server:test.mydomain.com x-forwarded-ssl:on x-forwarded-uri:/favicon.ico x-original-method:GET x-original-url:https://test.mydomain.com/favicon.ico x-real-ip:192.168.2.26] size:0 status:200 text_status:OK took:2.55136ms]
time=2024-03-27T09:24:04Z level=info msg=started handling request http_request=map[headers:map[accept:image/avif,image/webp,*/* accept-encoding:gzip, deflate, br accept-language:en-US,en;q=0.5 cache-control:no-cache connection:close cookie:[ory_kratos_session=MTcxMTUyOTQxNnx6Q0xpYnRYbE9jakxkM05LLWVMYS02Q1N5bnBnR1hZQmR3VTFRMTJaMWZneVZUR0hCU2RKa2VEaU5GZkJ5dWZJRkhPdGNKbmgwN3VDY0h2d0tDT3ZGUmhwWkFfMGlaRkVEdkNIVWhubmo5WHo5V0diSGJYdmZvd3RrUFRoVFIwNkNETGlfRHJmaE5mMWRVT283SFpGSlBGQ1pFYnVIN0FiSnpISnFiaHlUaHVKR0FjZkVGV0dQRkdRQU5zOUxocUxUMnZzbWRYOFB3a3gzSkJoUjJNbzR6QVJHa21uTjdDemktaWF5azhHME80Rm1qdDRiOFdrdU84Wi1GVmg1WVdnQmZnckVIRy02eWlZTW1TekxnQ2t8Y_TSiwcfeY5FN5_mi6wPFZqxjdXBlTzL2DyL5_Ot9gc=] dnt:1 pragma:no-cache referer:https://test.mydomain.com/ sec-fetch-dest:image sec-fetch-mode:no-cors sec-fetch-site:same-origin sec-gpc:1 user-agent:Mozilla/5.0 (X11; Linux x86_64; rv:124.0) Gecko/20100101 Firefox/124.0 x-forwarded-for:192.168.2.26 x-forwarded-host:test.mydomain.com x-forwarded-method:GET x-forwarded-port:443 x-forwarded-proto:https x-forwarded-server:test.mydomain.com x-forwarded-ssl:on x-forwarded-uri:/favicon.ico x-original-method:GET x-original-url:https://test.mydomain.com/favicon.ico x-real-ip:192.168.2.26] host:test.mydomain.com method:GET path:/favicon.ico query:<nil> remote:[fd00:2::10]:56804 scheme:http]
time=2024-03-27T09:24:04Z level=info msg=completed handling request http_request=map[headers:map[accept:image/avif,image/webp,*/* accept-encoding:gzip, deflate, br accept-language:en-US,en;q=0.5 cache-control:no-cache connection:close cookie:[ory_kratos_session=MTcxMTUyOTQxNnx6Q0xpYnRYbE9jakxkM05LLWVMYS02Q1N5bnBnR1hZQmR3VTFRMTJaMWZneVZUR0hCU2RKa2VEaU5GZkJ5dWZJRkhPdGNKbmgwN3VDY0h2d0tDT3ZGUmhwWkFfMGlaRkVEdkNIVWhubmo5WHo5V0diSGJYdmZvd3RrUFRoVFIwNkNETGlfRHJmaE5mMWRVT283SFpGSlBGQ1pFYnVIN0FiSnpISnFiaHlUaHVKR0FjZkVGV0dQRkdRQU5zOUxocUxUMnZzbWRYOFB3a3gzSkJoUjJNbzR6QVJHa21uTjdDemktaWF5azhHME80Rm1qdDRiOFdrdU84Wi1GVmg1WVdnQmZnckVIRy02eWlZTW1TekxnQ2t8Y_TSiwcfeY5FN5_mi6wPFZqxjdXBlTzL2DyL5_Ot9gc=] dnt:1 pragma:no-cache referer:https://test.mydomain.com/ sec-fetch-dest:image sec-fetch-mode:no-cors sec-fetch-site:same-origin sec-gpc:1 user-agent:Mozilla/5.0 (X11; Linux x86_64; rv:124.0) Gecko/20100101 Firefox/124.0 x-forwarded-for:192.168.2.26 x-forwarded-host:test.mydomain.com x-forwarded-method:GET x-forwarded-port:443 x-forwarded-proto:https x-forwarded-server:test.mydomain.com x-forwarded-ssl:on x-forwarded-uri:/favicon.ico x-original-method:GET x-original-url:https://test.mydomain.com/favicon.ico x-real-ip:192.168.2.26] host:test.mydomain.com method:GET path:/favicon.ico query:<nil> remote:[fd00:2::10]:56804 scheme:http] http_response=map[headers:map[content-type:text/html; charset=utf-8] size:1168 status:404 text_status:Not Found took:180.073µs]
Relevant configuration
authenticators:
cookie_session:
enabled: true
config:
check_session_url: http://kratos:4433/sessions/whoami
preserve_path: true
extra_from: "@this"
subject_from: "identity.id"
only:
- ory_kratos_session
authorizers:
allow:
enabled: true
mutators:
noop:
enabled: true
access_rules:
matching_strategy: regexp
repositories:
- file:///home/ory/rules.yml
log:
level: trace
leak_sensitive_values: true
Version
v0.40.7
On which operating system are you observing this issue?
Linux
In which environment are you deploying?
Docker Compose
Additional Context
No response