1/* 2 * Copyright 2021 gRPC authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package authz 18 19import ( 20 "context" 21 22 "google.golang.org/grpc" 23 "google.golang.org/grpc/codes" 24 "google.golang.org/grpc/internal/xds/rbac" 25 "google.golang.org/grpc/status" 26) 27 28// StaticInterceptor contains engines used to make authorization decisions. It 29// either contains two engines deny engine followed by an allow engine or only 30// one allow engine. 31type StaticInterceptor struct { 32 engines rbac.ChainEngine 33} 34 35// NewStatic returns a new StaticInterceptor from a static authorization policy 36// JSON string. 37func NewStatic(authzPolicy string) (*StaticInterceptor, error) { 38 rbacs, err := translatePolicy(authzPolicy) 39 if err != nil { 40 return nil, err 41 } 42 chainEngine, err := rbac.NewChainEngine(rbacs) 43 if err != nil { 44 return nil, err 45 } 46 return &StaticInterceptor{*chainEngine}, nil 47} 48 49// UnaryInterceptor intercepts incoming Unary RPC requests. 50// Only authorized requests are allowed to pass. Otherwise, an unauthorized 51// error is returned to the client. 52func (i *StaticInterceptor) UnaryInterceptor(ctx context.Context, req interface{}, _ *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { 53 err := i.engines.IsAuthorized(ctx) 54 if err != nil { 55 if status.Code(err) == codes.PermissionDenied { 56 return nil, status.Errorf(codes.PermissionDenied, "unauthorized RPC request rejected") 57 } 58 return nil, err 59 } 60 return handler(ctx, req) 61} 62 63// StreamInterceptor intercepts incoming Stream RPC requests. 64// Only authorized requests are allowed to pass. Otherwise, an unauthorized 65// error is returned to the client. 66func (i *StaticInterceptor) StreamInterceptor(srv interface{}, ss grpc.ServerStream, _ *grpc.StreamServerInfo, handler grpc.StreamHandler) error { 67 err := i.engines.IsAuthorized(ss.Context()) 68 if err != nil { 69 if status.Code(err) == codes.PermissionDenied { 70 return status.Errorf(codes.PermissionDenied, "unauthorized RPC request rejected") 71 } 72 return err 73 } 74 return handler(srv, ss) 75} 76