1

I am using Google OAuth 2.0 for authentication of an installed desktop Java application. I am using the Google OAuth 2.0 Java Client Library.

When I make a call to request the user to authorize access to their Google Calendar, the “Request for Permission” webpage is displayed in the default browser, as expected. After the user clicks Cancel or Accept, the webpage displays the message:

Received verification code. Closing...

In Internet Explorer, the webpage is then closed. In Firefox and Chrome, however, the webpage remains open.

Is there a way to force the webpage to close (from my Java program)?

This is the code I am using that triggers the webpage (taken from the Google Developer's CalendarSample (http://samples.google-api-java-client.googlecode.com/hg-history/425c5ffc30178f21aea592bc989849ea7e3498fe/calendar-cmdline-sample/instructions.html):

// set up authorization code flow
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
    httpTransport, JSON_FACTORY, clientSecrets,
    Collections.singleton(CalendarScopes.CALENDAR)).setDataStoreFactory(dataStoreFactory)
    .build();
// authorize
return new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");
Clo Knibbe
  • 369
  • 2
  • 10
  • I believe you have to keep track of the Url and close it yourself; just like in android webviews. You have to get the verification code first; – Eenvincible Aug 12 '14 at 19:04
  • The Java Client Library code is retrieving the verification code, and I am able to access the calendar as expected. The problem is that the browser window doesn't close (on FF and Chrome). I don't think that having the url will enable me to close the browser tab. – Clo Knibbe Aug 12 '14 at 19:53

1 Answers1

2

I figured it out. The webpage which was not closing is created by LocalServerReceiver. LocalServerReciever.CallbackHandler.writeLandingHtml() contains the following:

doc.println("<script type='text/javascript'>");
// We open "" in the same window to trigger JS ownership of it, which lets
// us then close it via JS, at least on Chrome.
doc.println("window.setTimeout(function() {");
doc.println("    window.open('', '_self', ''); window.close(); }, 1000);");
doc.println("if (window.opener) { window.opener.checkToken(); }");
doc.println("</script>");

This code is attempting to take advantage of an exploit that allows JavaScript to close a page, even though the page was not opened by JS. That exploit still works on IE 11, but no longer works on FF 31 or Chrome 36.

After a great deal of searching, I have learned that it is no longer possible for JS to close a page that it did not open (with the exception of the extant exploit vulnerability in IE).

For my purposes, I “solved” the problem by modifying LocalServerReceiver slightly. I have changed the text of the message displayed on the webpage from:

Received verification code. Closing...

to:

Your response has been received.

Please close this window.

The (non-modified) source for LocalServerReceiver can be found here: https://code.google.com/p/google-oauth-java-client/source/browse/google-oauth-client-jetty/src/main/java/com/google/api/client/extensions/jetty/auth/oauth2/LocalServerReceiver.java?r=2624919183758196142f47c414e71db685e77de2

Clo Knibbe
  • 369
  • 2
  • 10