-
-
Notifications
You must be signed in to change notification settings - Fork 361
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
Decision API support for the nginx-ingress annotation nginx.ingress.kubernetes.io/auth-url #521
Comments
Also, please let me know if I'm missing something here and it's already simple to use the nginx-ingress auth-url annotation with |
For what it's worth, patching 3652a77 with this works for our usecase: diff --git a/api/decision.go b/api/decision.go
index 7347b13..0468f9a 100644
--- a/api/decision.go
+++ b/api/decision.go
@@ -22,6 +22,7 @@ package api
import (
"net/http"
+ "net/url"
"github.com/ory/oathkeeper/pipeline/authn"
"github.com/ory/oathkeeper/x"
@@ -52,12 +53,33 @@ func NewJudgeHandler(r decisionHandlerRegistry) *DecisionHandler {
func (h *DecisionHandler) ServeHTTP(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
if len(r.URL.Path) >= len(DecisionPath) && r.URL.Path[:len(DecisionPath)] == DecisionPath {
- r.URL.Scheme = "http"
- r.URL.Host = r.Host
- if r.TLS != nil {
- r.URL.Scheme = "https"
+ originalURL := r.Header.Get("X-Original-URL")
+ if originalURL == "" {
+ r.URL.Scheme = "http"
+ r.URL.Host = r.Host
+ if r.TLS != nil {
+ r.URL.Scheme = "https"
+ }
+ r.URL.Path = r.URL.Path[len(DecisionPath):]
+ } else {
+ url, err := url.Parse(originalURL)
+ if err != nil {
+ h.r.Logger().WithError(err).
+ WithFields(map[string]interface{}{
+ "http_method": r.Method,
+ "http_url": r.URL.String(),
+ "http_host": r.Host,
+ "http_user_agent": r.UserAgent(),
+ "granted": false,
+ "x_original_url": originalURL,
+ }).
+ Warn("Failed to parse X-Original-URL")
+ h.r.ProxyRequestHandler().HandleError(w, r, nil, err)
+ return
+ }
+
+ r.URL = url
}
- r.URL.Path = r.URL.Path[len(DecisionPath):]
h.decisions(w, r)
} else { |
Thank you for raising this. I think we'll add this with #487 as a dedicated k8s nginx ingress route (or alternative pure nginx)! |
@AlbinoDrought Just stumbled over this issue. Aren't you able to solve the problem with the I never tested this on kubernetes, but I made a small demo with docker compose where I ran in into the same issue with the host. I could solve it by proxying the header value to the auth request. So I got high hopes it will work with the kubernetes ingress, too. |
|
@aeneasr it looks like, we may introduce an additional configuration option to specify a strategy to get/build What do you think about that approach?
access_rules:
# traefix, nginx, etc
matching_url_strategy: default package main
import (
"errors"
"net/http"
"net/url"
)
type MatchURL struct {
*url.URL
Method string
}
type MatchURLBuilder interface {
BuildURL(r *http.Request) (*MatchURL, error)
}
var _ MatchURLBuilder = (*DefaultMatchURLBuilder)(nil)
type DefaultMatchURLBuilder struct {}
func (b *DefaultMatchURLBuilder) BuildURL(r *http.Request) (*MatchURL, error) {
return &MatchURL{
URL: r.URL,
Method: r.Method,
}, nil
}
type TraefikMatchURLBuilder struct {}
var _ MatchURLBuilder = (*TraefikMatchURLBuilder)(nil)
func (b *TraefikMatchURLBuilder) BuildURL(r *http.Request) (*MatchURL, error) {
u := &url.URL{
Scheme: r.Header.Get("X-Forwarded-Proto"),
Host: r.Header.Get("X-Forwarded-Host"),
Path: r.Header.Get("X-Forwarded-Uri"),
}
m := r.Header.Get("X-Forwarded-Method")
if len(m) == 0 {
return nil, errors.New("`X-Forwarded-Method` header is not set")
}
return &MatchURL{
URL: u,
Method: m,
}, nil
}
var matchURLBuilders = map[string]MatchURLBuilder {
"default": &DefaultMatchURLBuilder{},
"traefik": &TraefikMatchURLBuilder{},
// etc
} |
That’s also an interesting approach! Originally the idea was to have specific endpoints for the various services, which I think is still a valid path forward and also a bit easier to configure / get roght? |
I was able to integrate Oathkeeper with NGINX Ingress using the latest version of Oathkeeper (at least > nginx.ingress.kubernetes.io/auth-url: "http://oathkeeper-api.iam.svc.cluster.local:4456/decisions"
nginx.ingress.kubernetes.io/auth-method: GET
nginx.ingress.kubernetes.io/auth-response-headers: Authorization
nginx.ingress.kubernetes.io/auth-snippet: |
proxy_set_header X-Original-URL $request_uri;
proxy_set_header X-Forwarded-Method $request_method;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Uri $request_uri; But the issue of #461 still remains unsolved. |
Hello contributors! I am marking this issue as stale as it has not received any engagement from the community or maintainers for a year. That does not imply that the issue has no merit! If you feel strongly about this issue
Throughout its lifetime, Ory has received over 10.000 issues and PRs. To sustain that growth, we need to prioritize and focus on issues that are important to the community. A good indication of importance, and thus priority, is activity on a topic. Unfortunately, burnout has become a topic of concern amongst open-source projects. It can lead to severe personal and health issues as well as opening catastrophic attack vectors. The motivation for this automation is to help prioritize issues in the backlog and not ignore, reject, or belittle anyone. If this issue was marked as stale erroneously you can exempt it by adding the Thank you for your understanding and to anyone who participated in the conversation! And as written above, please do participate in the conversation if this topic is important to you! Thank you 🙏✌️ |
Is your feature request related to a problem? Please describe.
We are using
nginx-ingress
with thenginx.ingress.kubernetes.io/auth-url
annotation.We want to apply an access rule to this URL: https://admin.site.example/dashboard
We have an ingress config that looks like this:
Oathkeeper expects (correct me if I'm wrong) a request that looks like this:
Oathkeeper will actually receive:
The default nginx-ingress template generates an NGINX config where the
Host
header sent to Oathkeeper is the auth_request hostoathkeeper.site.example
instead of our target hostadmin.site.example
:Generated nginx-ingress config
Describe the solution you'd like
I would like to be able to point the
auth-url
annotation at Oathkeeper and have everything work without changing any internal nginx-ingress config templates.Describe alternatives you've considered
The default template includes all the normal X-Forwarded-* headers. It may work out-of-the-box with the
/decisions/traefik
endpoint added in #486 , but I'm not sure if this is released yet.Additional context
oryd/oathkeeper:v0.38.3-beta.1
quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.32.0
The text was updated successfully, but these errors were encountered: