Python gRPC自签名证书认证遇StatusCode.UNAUTHENTICATED问题求助
解决gRPC Python客户端UNAUTHENTICATED(401)错误
问题根源
- 调用凭证未关联通道:你生成了
metadata_call_credentials但未将其与SSL通道凭证组合,也没有把最终凭证传递给secure_channel,导致Basic Auth的Authorization元数据根本没发送到服务器。 - GrpcAuth插件实现可能不规范:如果
GrpcAuth没有遵循gRPC的AuthMetadataPlugin接口要求,无法正确注入认证头。
解决方案
步骤1:正确实现GrpcAuth认证插件
确保你的GrpcAuth类继承并实现grpc.AuthMetadataPlugin的__call__方法:
import grpc class GrpcAuth(grpc.AuthMetadataPlugin): def __init__(self, auth_token): self._auth_token = auth_token def __call__(self, context, callback): # 返回包含Authorization头的元数据 metadata = (('authorization', self._auth_token),) callback(metadata, None)
步骤2:组合通道凭证与调用凭证
将SSL通道凭证和Basic Auth调用凭证组合成复合凭证,再创建安全通道:
import base64 import grpc # 导入你的proto生成文件 import report_service_pb2_grpc # 读取证书 with open('./foo.crt', 'rb') as file: certificate = file.read() # 创建SSL通道凭证 channel_creds = grpc.ssl_channel_credentials(root_certificates=certificate) # 生成Basic Auth token token = base64.b64encode(f'{username}:{password}'.encode('utf-8')).decode('ascii') auth_plugin = GrpcAuth(f'Basic {token}') # 创建调用凭证 call_creds = grpc.metadata_call_credentials(auth_plugin) # 组合通道凭证和调用凭证 composite_creds = grpc.composite_channel_credentials(channel_creds, call_creds) # 使用复合凭证创建通道 channel = grpc.secure_channel(target=server_url, credentials=composite_creds) # 创建stub并发起请求 stub = report_service_pb2_grpc.ABCServiceStub(channel=channel) req_data = input_param_to_protobuf(request_data) try: # 注意:def是Python关键字,检查proto方法名是否合法,比如改为stub.GetReport(req_data) response = stub.def(req_data) print("Response received:", response) except grpc.RpcError as e: print(f"Error code: {e.code()}, details: {e.details()}")
额外检查项
- 确认
username和password与API-DOG中使用的完全一致。 - 检查服务器URL是否包含正确端口(gRPC常用443或自定义端口)。
- 如果服务器要求双向认证,需补充
private_key和certificate_chain参数到ssl_channel_credentials中(当前场景为单向认证,无需额外配置)。 - 注意:
def是Python关键字,proto文件中的方法名不能为def,生成stub后需使用合法的方法名调用。
内容的提问来源于stack exchange,提问作者Mandar Pande
相关产品推荐
相关产品推荐

