This is an automated email from the ASF dual-hosted git repository.
zeroshade pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-go.git
The following commit(s) were added to refs/heads/main by this push:
new 6831fe05 fix(flight): return Unauthenticated for invalid unary auth
tokens (#1070)
6831fe05 is described below
commit 6831fe05787ee64e0bccb2af52ae06332b229198
Author: Minh Vu <[email protected]>
AuthorDate: Wed Aug 5 19:57:19 2026 +0200
fix(flight): return Unauthenticated for invalid unary auth tokens (#1070)
## Problem
The legacy Flight authentication interceptors reported the same invalid
token differently: stream RPCs returned `Unauthenticated`, while unary
RPCs returned `PermissionDenied`. Clients could not reliably distinguish
invalid credentials from insufficient authorization.
## Change
Return gRPC `Unauthenticated` from the unary interceptor when
`ServerAuthHandler.IsValid` rejects a token, matching the stream
interceptor.
## Coverage
A focused interceptor test verifies the status code and confirms that
the request handler is not invoked after authentication fails.
## Validation
`go test ./arrow/flight`
---
arrow/flight/server_auth.go | 2 +-
arrow/flight/server_auth_internal_test.go | 51 +++++++++++++++++++++++++++++++
2 files changed, 52 insertions(+), 1 deletion(-)
diff --git a/arrow/flight/server_auth.go b/arrow/flight/server_auth.go
index de660186..ab1ee06d 100644
--- a/arrow/flight/server_auth.go
+++ b/arrow/flight/server_auth.go
@@ -109,7 +109,7 @@ func serverAuthUnaryInterceptor(ctx context.Context, req
interface{}, srv *grpc.
peerIdentity, err := auth.IsValid(authTok)
if err != nil {
- return nil, status.Errorf(codes.PermissionDenied, "auth-error:
%s", err)
+ return nil, status.Errorf(codes.Unauthenticated, "auth-error:
%s", err)
}
return handler(context.WithValue(ctx, authCtxKey{}, peerIdentity), req)
diff --git a/arrow/flight/server_auth_internal_test.go
b/arrow/flight/server_auth_internal_test.go
new file mode 100644
index 00000000..16985590
--- /dev/null
+++ b/arrow/flight/server_auth_internal_test.go
@@ -0,0 +1,51 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package flight
+
+import (
+ "context"
+ "errors"
+ "testing"
+
+ "google.golang.org/grpc"
+ "google.golang.org/grpc/codes"
+ "google.golang.org/grpc/status"
+)
+
+type rejectingAuth struct{}
+
+func (rejectingAuth) Authenticate(AuthConn) error { return nil }
+func (rejectingAuth) IsValid(string) (interface{}, error) {
+ return nil, errors.New("invalid token")
+}
+
+type rejectingAuthServer struct{ auth ServerAuthHandler }
+
+func (s rejectingAuthServer) GetAuthHandler() ServerAuthHandler { return
s.auth }
+
+func TestServerAuthUnaryInterceptorInvalidToken(t *testing.T) {
+ _, err := serverAuthUnaryInterceptor(context.Background(), nil,
&grpc.UnaryServerInfo{
+ Server: rejectingAuthServer{auth: rejectingAuth{}},
+ }, func(context.Context, interface{}) (interface{}, error) {
+ t.Fatal("handler called for an invalid token")
+ return nil, nil
+ })
+ if got, want := status.Code(err), codes.Unauthenticated; got != want {
+ t.Fatalf("unexpected status code: got %v, want %v", got, want)
+ }
+}