Skip to content
41 changes: 39 additions & 2 deletions oauth2_http/java/com/google/auth/oauth2/UserCredentials.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import com.google.api.client.util.GenericData;
import com.google.api.client.util.Preconditions;
import com.google.auth.http.HttpTransportFactory;
import com.google.common.annotations.Beta;
import com.google.common.base.MoreObjects;
import java.io.ByteArrayInputStream;
import java.io.IOException;
Expand All @@ -58,12 +59,14 @@
import java.util.Objects;

/** OAuth2 Credentials representing a user's identity and consent. */
public class UserCredentials extends GoogleCredentials implements QuotaProjectIdProvider {
public class UserCredentials extends GoogleCredentials
implements QuotaProjectIdProvider, IdTokenProvider {

private static final String GRANT_TYPE = "refresh_token";
private static final String PARSE_ERROR_PREFIX = "Error parsing token refresh response. ";
private static final long serialVersionUID = -4800758775038679176L;

public static final String GOOGLE_CLIENT_ID = "32555940559.apps.googleusercontent.com";
public static final String GOOGLE_CLIENT_SECRET = "ZmssLNjJy2998hD4CTg2ejr2";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's arguable how secret these are when they ship in binaries, but in the past security team has advised me in other projects not to put these values in github but to bundle them in at build time.

Please file a ticket for an internal security review on this.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, Google Client_id and secret (Yes, Google, because it's not my secrets, but Google secrets!) are clear and it can seem not safe. But, I don't think that is a real "secret".

I'm not sure to catch what change if you add only these values at build time? The library will be ship with the secret in plain text and a simple IDE allow you to easily find them..

Here how I found the Google secrets

gcloud config set log_http_redact_token false
gcloud auth print-identity-token --log-http

You can see the request body in clear with this client_id and client_secret

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@elharo I created the issue #472. I let you forwarding it internally.

If required, I will be happy to participate to discussion (I'm a GDE and thus already under NDA)

private final String clientId;
private final String clientSecret;
private final String refreshToken;
Expand Down Expand Up @@ -340,6 +343,40 @@ public String getQuotaProjectId() {
return quotaProjectId;
}

/**
* Returns a Google ID Token from the user credential
*
* @param targetAudience currently unused for UserCredential.
* @param options list of Credential specific options for for the token. Currently unused for
* UserCredentials.
* @throws IOException if the attempt to get an IdToken failed
* @return IdToken object which includes the raw id_token and expiration
*/
@Beta
@Override
public IdToken idTokenWithAudience(String targetAudience, List<Option> options)
throws IOException {
JsonFactory jsonFactory = OAuth2Utils.JSON_FACTORY;

GenericData tokenRequest = new GenericData();
tokenRequest.set("grant_type", GRANT_TYPE);
tokenRequest.set("client_id", GOOGLE_CLIENT_ID);
tokenRequest.set("client_secret", GOOGLE_CLIENT_SECRET);
tokenRequest.set("refresh_token", this.refreshToken);

UrlEncodedContent content = new UrlEncodedContent(tokenRequest);

HttpRequestFactory requestFactory = transportFactory.create().createRequestFactory();
HttpRequest request = requestFactory.buildPostRequest(new GenericUrl(tokenServerUri), content);
request.setParser(new JsonObjectParser(jsonFactory));
request.setCurlLoggingEnabled(true);
HttpResponse response = request.execute();

GenericData responseData = response.parseAs(GenericData.class);
String rawToken = OAuth2Utils.validateString(responseData, "id_token", PARSE_ERROR_PREFIX);
return IdToken.create(rawToken);
}

public static class Builder extends GoogleCredentials.Builder {

private String clientId;
Expand Down