我目前正在将应用程序从jersey 1迁移到2.在旧应用程序中,我们为所有自动刷新过期OAuth令牌的球衣客户端使用ClientFilter
,如下所示:
@Override
public ClientResponse handle(ClientRequest cr) {
ClientResponse resp = getNext().handle(cr);
if (resp.getStatus() == Status.UNAUTHORIZED.getStatusCode()) {
// Try to refresh the token
boolean refreshed = refreshToken(oAuthInfo);
if (refreshed) {
resp = getNext().handle(cr);
}
}
return resp;
}
它可能不是最优雅的方式,但好处是休息客户端用户不必关心过期的令牌。
对于球衣2的ContainerResponseFilter
,这似乎不再那么简单了。我目前看到的唯一选项是使用ClientRequestContext
并尝试使用getClient
,getHeaders
等重新创建原始请求...然后在{{1}更新结果}。然而,这似乎有点笨重,所以我想知道是否有更方便的方式来刷新OAuth令牌而不必在使用泽西客户端的任何地方处理它?</ p>
答案 0 :(得分:0)
看起来没有比使用客户端过滤器拦截响应更方便的方法,在需要时刷新令牌并尝试使用新令牌重复完全相同的请求。事实上,这种方法也被泽西岛自己的过滤器类使用。
在过滤器类中重复原始休息呼叫的示例代码可以在jerseys HttpAuthenticationFilter中找到:
static boolean repeatRequest(ClientRequestContext request, ClientResponseContext response, String newAuthorizationHeader) {
Client client = request.getClient();
String method = request.getMethod();
MediaType mediaType = request.getMediaType();
URI lUri = request.getUri();
WebTarget resourceTarget = client.target(lUri);
Invocation.Builder builder = resourceTarget.request(mediaType);
MultivaluedMap<String, Object> newHeaders = new MultivaluedHashMap<String, Object>();
for (Map.Entry<String, List<Object>> entry : request.getHeaders().entrySet()) {
if (HttpHeaders.AUTHORIZATION.equals(entry.getKey())) {
continue;
}
newHeaders.put(entry.getKey(), entry.getValue());
}
newHeaders.add(HttpHeaders.AUTHORIZATION, newAuthorizationHeader);
builder.headers(newHeaders);
builder.property(REQUEST_PROPERTY_FILTER_REUSED, "true");
Invocation invocation;
if (request.getEntity() == null) {
invocation = builder.build(method);
} else {
invocation = builder.build(method,
Entity.entity(request.getEntity(), request.getMediaType()));
}
Response nextResponse = invocation.invoke();
if (nextResponse.hasEntity()) {
response.setEntityStream(nextResponse.readEntity(InputStream.class));
}
MultivaluedMap<String, String> headers = response.getHeaders();
headers.clear();
headers.putAll(nextResponse.getStringHeaders());
response.setStatus(nextResponse.getStatus());
return response.getStatus() != Response.Status.UNAUTHORIZED.getStatusCode();
}
此代码用于DigestAuthenticator或BasicAuthenticator,以便在收到服务器Unauthorised
响应的情况下重复提供凭据的请求。