使用jersey 2客户端刷新OAuth令牌

时间:2018-03-02 15:13:53

标签: java jersey jersey-2.0 jersey-client

我目前正在将应用程序从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并尝试使用getClientgetHeaders等重新创建原始请求...然后在{{1}更新结果}。然而,这似乎有点笨重,所以我想知道是否有更方便的方式来刷新OAuth令牌而不必在使用泽西客户端的任何地方处理它?<​​/ p>

1 个答案:

答案 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();
}

此代码用于DigestAuthenticatorBasicAuthenticator,以便在收到服务器Unauthorised响应的情况下重复提供凭据的请求。

相关问题