Skip to content

google-oauth-java-client: AbstractAuthorizationCodeCallbackServlet is blocked because of locks #1071

Open
@krog78

Description

@krog78

Environment details

https://github.com/googleapis/google-oauth-java-client/blob/main/google-oauth-client-servlet/src/main/java/com/google/api/client/extensions/servlet/auth/oauth2/AbstractAuthorizationCodeCallbackServlet.java

Steps to reproduce

  1. Send multiple times by second request to the callback URL
  2. Threads are blocked because of the ReentrantLock()

Code example

/** Lock on the flow. */
  private final Lock lock = new ReentrantLock();

  /**
   * Authorization code flow to be used across all HTTP servlet requests or {@code null} before
   * initialized in {@link #initializeFlow()}.
   */
  private AuthorizationCodeFlow flow;

  @Override
  protected final void doGet(HttpServletRequest req, HttpServletResponse resp)
      throws ServletException, IOException {
    StringBuffer buf = req.getRequestURL();
    if (req.getQueryString() != null) {
      buf.append('?').append(req.getQueryString());
    }
    AuthorizationCodeResponseUrl responseUrl = new AuthorizationCodeResponseUrl(buf.toString());
    String code = responseUrl.getCode();
    if (responseUrl.getError() != null) {
      onError(req, resp, responseUrl);
    } else if (code == null) {
      resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
      resp.getWriter().print("Missing authorization code");
    } else {
      lock.lock();
      try {
        if (flow == null) {
          flow = initializeFlow();
        }
        String redirectUri = getRedirectUri(req);
        TokenResponse response = flow.newTokenRequest(code).setRedirectUri(redirectUri).execute();
        String userId = getUserId(req);
        Credential credential = flow.createAndStoreCredential(response, userId);
        onSuccess(req, resp, credential);
      } finally {
        lock.unlock();
      }
    }
  }

Any additional information below

If there are lots of requests, the Threads are blocked and waiting for the lock from other threads.
What the purpose of the lock? Is it onlyuseful for initializeFlow()?
Is the rest of the process thread safe?

Can we put

 String redirectUri = getRedirectUri(req);
        TokenResponse response = flow.newTokenRequest(code).setRedirectUri(redirectUri).execute();
        String userId = getUserId(req);
        Credential credential = flow.createAndStoreCredential(response, userId);
        onSuccess(req, resp, credential);

outside the lock?

Thanks
Regards,
Sylvain

Metadata

Metadata

Assignees

No one assigned

    Labels

    priority: p3Desirable enhancement or fix. May not be included in next release.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions