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");
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