开发基于gRPC协议的自定义授权服务

服务网格 ASM(Service Mesh)支持完善的认证、授权配置,还提供了灵活的扩展能力,支持对接HTTP协议和gRPC协议的自定义授权服务,并接入网格的鉴权流程。本文介绍如何开发一个基于HTTP协议的自定义授权服务。

背景信息

开发基于HTTP协议的自定义授权服务中介绍了自定义授权服务的架构。与HTTP协议自定义授权服务不同,gRPC协议自定义授权服务收到的消息并不是一个HTTP请求,而是一个Envoy专用的gRPC消息。您需要做的就是从Envoy提供的信息中判断是否放行请求。

配置介绍

ASM支持使用界面关联一个自定义授权服务,关联之后您可以在授权策略中配置要使用鉴权服务的网格代理。具体操作,请参见使用gRPC协议对接自定义授权服务

gRPC协议的自定义授权服务配置比较少,和HTTP协议的自定义授权服务相比没有Header相关配置。您可以直接从gRPC的鉴权请求中拿到所有Header。

开发gRPC自定义授权服务

ASM兼容开源Istio服务网格,Istio社区提供了自定义授权服务的开发示例。这部分代码中同时实现了HTTP和gRPC两种协议的自定义授权服务。本文涉及的gRPC部分主要逻辑在extAuthzServerV3这个结构体中:

type extAuthzServerV3 struct{}
func (s *extAuthzServerV3) Check(_ context.Context, request *authv3.CheckRequest) (*authv3.CheckResponse, error)
func (s *extAuthzServerV3) allow(request *authv3.CheckRequest) *authv3.CheckResponse
func (s *extAuthzServerV3) deny(request *authv3.CheckRequest) *authv3.CheckResponse
func (s *extAuthzServerV3) logRequest(allow string, request *authv3.CheckRequest)

这个结构体主要实现了AuthorizationServer接口,接口定义如下:

type AuthorizationServer interface {
	// Performs authorization check based on the attributes associated with the
	// incoming request, and returns status `OK` or not `OK`.
	Check(context.Context, *CheckRequest) (*CheckResponse, error)
}

主要的逻辑在自行实现的Check函数中:

// Check implements gRPC v3 check request.
func (s *extAuthzServerV3) Check(_ context.Context, request *authv3.CheckRequest) (*authv3.CheckResponse, error) {
	attrs := request.GetAttributes()

	// Determine whether to allow or deny the request.
	allow := false
	checkHeaderValue, contains := attrs.GetRequest().GetHttp().GetHeaders()[checkHeader]
	if contains {
		allow = checkHeaderValue == allowedValue
	} else {
		allow = attrs.Source != nil && strings.HasSuffix(attrs.Source.Principal, "/sa/"+*serviceAccount)
	}

	if allow {
		return s.allow(request), nil
	}

	return s.deny(request), nil
}

可以看出,此函数判断了一个请求的header,如果这个header的值是allowedValue就返回allow函数的结果;如果没有这个header,则检查attrs.Source.Principal的值是否是一个预先配置好的值。

关于authv3.CheckRequest中各个字段的详细含义,请参见Envoy Proto或Envoy的go-control-plane说明。

Istio提供的示例代码中还包含了一个extAuthzServerV2结构体。Envoy已经弃用了V2相关的API,您当前只需要实现这里提到的V3版本的gRPC接口即可。

配置自定义授权服务

在ACK集群中部署上一步开发的自定义授权服务后,您可以开始自定义授权服务的接入。具体操作,请参见接入gRPC协议的自定义授权服务