Spring Boot Starter gRPC测试失败:ServerInterceptor致非授权测试中断
解决gRPC拦截器导致测试未授权失败的几种方案
方案一:给测试请求添加合法JWT头
直接在测试代码里构造包含有效JWT的Metadata,发起请求时带上即可:
// 构造测试用的Metadata Metadata metadata = new Metadata(); // 填入能通过validateUserToken校验的测试Token metadata.put(Metadata.Key.of("JWT", Metadata.ASCII_STRING_MARSHALLER), "test-valid-jwt-token"); // 给Stub添加拦截器,在请求头中传入Metadata YourServiceStub stub = YourServiceGrpc.newBlockingStub(channel); stub = stub.withInterceptors(new ClientInterceptor() { @Override public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall( MethodDescriptor<ReqT, RespT> method, CallOptions callOptions, Channel next) { return new ForwardingClientCall.SimpleForwardingClientCall<>(next.newCall(method, callOptions)) { @Override public void start(Listener<RespT> responseListener, Metadata headers) { headers.merge(metadata); super.start(responseListener, headers); } }; } }); // 发起测试请求 stub.yourRpcMethod(request);
方案二:测试环境替换拦截器
启动测试用的gRPC服务时,用测试专用的拦截器替代正式的权限校验拦截器,直接跳过验证逻辑:
// 测试专用拦截器 public class TestGrpcServerRequestInterceptor implements ServerInterceptor { @Override public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall( ServerCall<ReqT, RespT> serverCall, Metadata metadata, ServerCallHandler<ReqT, RespT> next) { // 测试环境直接放行,不做Token校验 log.info("测试环境跳过Token验证"); return next.startCall(serverCall, metadata); } }
在测试配置中注册这个拦截器,替换正式的GrpcServerRequestInterceptor即可。
方案三:给正式拦截器添加白名单机制
修改正式的拦截器,加入白名单判断,让指定的测试服务/方法跳过权限校验:
public class GrpcServerRequestInterceptor implements ServerInterceptor { // 白名单:填入需要跳过校验的服务方法全限定名 private static final Set<String> WHITELISTED_METHODS = Set.of( "com.example.TestService/TestMethod", "com.example.DemoService/DemoMethod" ); @Override public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall( ServerCall<ReqT, RespT> serverCall, Metadata metadata, ServerCallHandler<ReqT, RespT> next) { String methodFullName = serverCall.getMethodDescriptor().getFullMethodName(); // 命中白名单则直接放行 if (WHITELISTED_METHODS.contains(methodFullName)) { log.info("方法在白名单内,跳过Token验证"); return next.startCall(serverCall, metadata); } log.info("Validating user token"); var userToken = metadata.get(Metadata.Key.of("JWT", Metadata.ASCII_STRING_MARSHALLER)); validateUserToken(userToken); return next.startCall(serverCall, metadata); } private void validateUserToken(String userToken) { // Logic to validate token } }
内容的提问来源于stack exchange,提问作者Hugo Connti
相关产品推荐
相关产品推荐

