google-oauthgoogle-oauth-java-client

Google OAuth2 Java API set state in callback/redirect URI


I would like to set the state parameter in my Redirect URI as described in https://developers.google.com/identity/protocols/oauth2/web-server#redirecting

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly&
 access_type=offline&
 include_granted_scopes=true&
 response_type=code&
 state=state_parameter_passthrough_value&
 redirect_uri=https%3A//oauth2.example.com/code&
 client_id=client_id

My code is per Google's documentation at https://developers.google.com/api-client-library/java/google-api-java-client/oauth2#web_server_applications

public class CalendarServletSample extends AbstractAuthorizationCodeServlet {

  @Override
  protected void doGet(HttpServletRequest request, HttpServletResponse response)
      throws IOException {
    // do stuff
  }

  @Override
  protected String getRedirectUri(HttpServletRequest req) throws ServletException, IOException {
    GenericUrl url = new GenericUrl(req.getRequestURL().toString());
    url.setRawPath("/oauth2callback");
    return url.build();
  }

  @Override
  protected AuthorizationCodeFlow initializeFlow() throws IOException {
    return new GoogleAuthorizationCodeFlow.Builder(
        new NetHttpTransport(), GsonFactory.getDefaultInstance(),
        "[[ENTER YOUR CLIENT ID]]", "[[ENTER YOUR CLIENT SECRET]]",
        Collections.singleton(CalendarScopes.CALENDAR)).setDataStoreFactory(
        DATA_STORE_FACTORY).setAccessType("offline").build();
  }

  @Override
  protected String getUserId(HttpServletRequest req) throws ServletException, IOException {
    // return user ID
  }
}

How can I set the state in my redirect URI?

I tried this:

@Override
  protected String getRedirectUri(HttpServletRequest req) throws ServletException, IOException {
    GenericUrl url = new GenericUrl(req.getRequestURL().toString());
    url.setRawPath("/oauth2callback");
    url.set("state", "myspecialname");
    return url.build();
  }

But Google tells me:

Authorization Error
Error 400: invalid_request
Invalid redirect_uri contains reserved response param state

Solution

  • This answer is to override onAuthorization:

    @Override
    protected void onAuthorization(HttpServletRequest req, HttpServletResponse resp,
      AuthorizationCodeRequestUrl authorizationUrl) throws ServletException, IOException {
        authorizationUrl.setState("myspecialstate");
        super.onAuthorization(req, resp, authorizationUrl);
    }