I'm using ingress-nginx and getting infinite redirects when issuing a 302 redirect in my backend service.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: main-ing
namespace: default
annotations:
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
spec:
ingressClassName: nginx
rules:
- host: service.example.com
http:
paths:
- pathType: Prefix
path: /
backend:
service:
name: prometheus-service
port:
number: 443
- host: login.example.com
http:
paths:
- pathType: Prefix
path: /
backend:
service:
name: authentication-grant-service
port:
number: 443
I hit https://service.example.com
and if auth fails, I redirect to https://login.example.com
, which somehow results in an infinite loop.
Additionally, I notice that the request actually just goes straight back into service.example.com
and fails continuously in a loop.
func unauthorizedPage(logger *zap.Logger, w http.ResponseWriter, req *http.Request) {
logger.Error("The user is not authorized to make this request - referring",
zap.String("refer", req.Host+req.URL.Path))
for name, values := range req.Header {
for _, value := range values {
fmt.Println(name, value)
}
}
http.Redirect(w,
req,
"https://login.example.com",
http.StatusFound)
}
Logs:
{"level":"error","ts":1658531352.658133,"caller":"proxy/proxy.go:30","msg":"The user is not authorized to make this request - referring","refer":"service.example.com/","....
{"level":"error","ts":1658531352.658133,"caller":"proxy/proxy.go:30","msg":"The user is not authorized to make this request - referring","refer":"login.example.com/","....
How is this even possible? If you notice in the logs above, first it shows the expected refer
value, then it shows the refer
for the login page, which shouldn't be possible since the login page has no relation to this service. This tells me it's some nginx issue.
Is this because it (internally) reaches out to my login service, fetches a response and it returns back through the service route again, validates, fails and that process just continues over and over again?
Attempted Fix
// unauthorizedPage is the default redirect page
func unauthorizedPage(logger *zap.Logger, w http.ResponseWriter, req *http.Request) {
refer := req.Host + req.URL.Path
if refer != "service.example.com/" {
logger.Info("Not failing request since redundant", zap.String("refer", refer))
return
}
logger.Error("The user is not authorized to make this request - referring",
zap.String("refer", req.Host+req.URL.Path))
for name, values := range req.Header {
for _, value := range values {
fmt.Println(name, value)
}
}
http.Redirect(w,
req,
"https://login.example.com",
http.StatusFound)
}
In this case, it doesn't fail and redirect on auth if the request is the login page, I just let it proxy through. However, in this case, I get a white page in my response.