【发布时间】:2018-05-04 23:37:36
【问题描述】:
我正在尝试使用拦截器在我的 gRPC 服务器和客户端应用程序之间实现 OAuth2,步骤如下:
- 客户端应用调用服务器的 gRPC 方法
- 服务器应用响应
UNAUTHENTICATED状态和标题中的redirect-url - client获取
redirect-url,用它访问Authorization server,最后得到access_token - 客户端应用调用服务器的 gRPC 方法(这次使用
access_token)
但是,第 4 步似乎不可能仅在一次调用中完成,因为事务已经在第 2 步关闭。有没有办法在一次 gRPC 服务调用中完成这 4 个步骤?
这是我的 ClientInterceptor 类。我在代码中指出了 4 个步骤(参见代码 cmets)。
public class OAuthClientInterceptor implements ClientInterceptor {
@Override
public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(MethodDescriptor<ReqT, RespT> method, CallOptions callOptions, Channel next) {
return new CheckedForwardingClientCall<ReqT, RespT>(next.newCall(method, callOptions)) {
@Override
public void checkedStart(Listener<RespT> responseListener, Metadata headers) {
if (redirectUrl != null) {
try {
//[Step #3] Obtain the access token
accessToken = obtainAccessToken(redirectUrl);
} catch (ConnectException e) {
throw new StatusRuntimeException(Status.UNAUTHENTICATED.withCause(e));
}
}
if (accessToken != null) {
headers.put(Key.of("Authorization",
Metadata.ASCII_STRING_MARSHALLER), "Bearer " + accessToken);
}
if (recursiveCall) {
//[Step #4] PROBLEM: still results to UNAUTHENTICATED
next.newCall(method, callOptions).start(responseListener, headers);
recursiveCall = false;
return;
}
OAuthResponseListener<RespT> oAuthRespListener = new OAuthResponseListener(responseListener);
oAuthRespListener.setUnauthenticatedListener(trailers->{
//[Step #2] Obtain the redirect-url
redirectUrl = trailers.get(Key.of("redirect-url", Metadata.ASCII_STRING_MARSHALLER));
recursiveCall = true;
//[Step #3 and 4] Invoke the retrieval of access token and the 2nd call to gRPC method
checkedStart(responseListener, headers);
});
//[Step #1] Call the gRPC method
delegate().start(oAuthRespListener, headers);
}
};
}
}
【问题讨论】:
-
嘿,我在 grpc-java GitHub 账号上问过这个问题,这里是链接github.com/grpc/grpc-java/issues/6638
-
这里是github上这个问题的答案。 github.com/grpc/grpc-java/issues/5856#issuecomment-511077021
标签: java oauth-2.0 spring-security-oauth2 grpc-java