Fix forwarding of auth-response-headers to gRPC backends (#7331)

* add e2e test for auth-response-headers annotation

* add e2e test for grpc with auth-response-headers

* fix forwarding of auth header to GRPC backends

* add test case for proxySetHeader(nil)
This commit is contained in:
Tom Hayward 2021-07-12 23:08:29 -07:00 committed by Kubernetes Prow Robot
parent c9d5b21a65
commit 9a9ad47857
5 changed files with 136 additions and 22 deletions

View file

@ -453,6 +453,29 @@ http {
Expect().
Status(http.StatusOK)
})
ginkgo.It("should overwrite Foo header with auth response", func() {
var (
rewriteHeader = "Foo"
rewriteVal = "bar"
)
annotations["nginx.ingress.kubernetes.io/auth-response-headers"] = rewriteHeader
f.UpdateIngress(ing)
f.WaitForNginxServer(host, func(server string) bool {
return strings.Contains(server, fmt.Sprintf("proxy_set_header '%s' $authHeader0;", rewriteHeader))
})
f.HTTPTestClient().
GET("/").
WithHeader("Host", host).
WithHeader(rewriteHeader, rewriteVal).
WithBasicAuth("user", "password").
Expect().
Status(http.StatusOK).
Body().
NotContainsFold(fmt.Sprintf("%s=%s", rewriteHeader, rewriteVal))
})
})
ginkgo.Context("when external authentication is configured with a custom redirect param", func() {

View file

@ -27,6 +27,7 @@ import (
"golang.org/x/net/context"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/metadata"
core "k8s.io/api/core/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -121,6 +122,79 @@ var _ = framework.DescribeAnnotation("backend-protocol - GRPC", func() {
assert.Equal(ginkgo.GinkgoT(), metadata["content-type"].Values[0], "application/grpc")
})
ginkgo.It("authorization metadata should be overwritten by external auth response headers", func() {
f.NewGRPCBinDeployment()
f.NewHttpbinDeployment()
host := "echo"
svc := &core.Service{
ObjectMeta: metav1.ObjectMeta{
Name: "grpcbin-test",
Namespace: f.Namespace,
},
Spec: corev1.ServiceSpec{
ExternalName: fmt.Sprintf("grpcbin.%v.svc.cluster.local", f.Namespace),
Type: corev1.ServiceTypeExternalName,
Ports: []corev1.ServicePort{
{
Name: host,
Port: 9000,
TargetPort: intstr.FromInt(9000),
Protocol: "TCP",
},
},
},
}
f.EnsureService(svc)
err := framework.WaitForEndpoints(f.KubeClientSet, framework.DefaultTimeout, framework.HTTPBinService, f.Namespace, 1)
assert.Nil(ginkgo.GinkgoT(), err)
e, err := f.KubeClientSet.CoreV1().Endpoints(f.Namespace).Get(context.TODO(), framework.HTTPBinService, metav1.GetOptions{})
assert.Nil(ginkgo.GinkgoT(), err)
assert.GreaterOrEqual(ginkgo.GinkgoT(), len(e.Subsets), 1, "expected at least one endpoint")
assert.GreaterOrEqual(ginkgo.GinkgoT(), len(e.Subsets[0].Addresses), 1, "expected at least one address ready in the endpoint")
httpbinIP := e.Subsets[0].Addresses[0].IP
annotations := map[string]string{
"nginx.ingress.kubernetes.io/auth-url": fmt.Sprintf("http://%s/response-headers?authorization=foo", httpbinIP),
"nginx.ingress.kubernetes.io/auth-response-headers": "Authorization",
"nginx.ingress.kubernetes.io/backend-protocol": "GRPC",
}
ing := framework.NewSingleIngressWithTLS(host, "/", host, []string{host}, f.Namespace, "grpcbin-test", 9000, annotations)
f.EnsureIngress(ing)
f.WaitForNginxServer(host,
func(server string) bool {
return strings.Contains(server, "grpc_pass grpc://upstream_balancer;")
})
conn, _ := grpc.Dial(f.GetNginxIP()+":443",
grpc.WithTransportCredentials(
credentials.NewTLS(&tls.Config{
ServerName: "echo",
InsecureSkipVerify: true,
}),
),
)
defer conn.Close()
client := pb.NewGRPCBinClient(conn)
ctx := metadata.AppendToOutgoingContext(context.Background(),
"authorization", "bar")
res, err := client.HeadersUnary(ctx, &pb.EmptyMessage{})
assert.Nil(ginkgo.GinkgoT(), err)
metadata := res.GetMetadata()
assert.Equal(ginkgo.GinkgoT(), "foo", metadata["authorization"].Values[0])
})
ginkgo.It("should return OK for service with backend protocol GRPCS", func() {
f.NewGRPCBinDeployment()