All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier Maven / Gradle / Ivy

/*
 * Copyright 2012 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */

package com.google.api.client.googleapis.auth.oauth2;

import com.google.api.client.auth.openidconnect.IdToken;
import com.google.api.client.auth.openidconnect.IdTokenVerifier;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.util.Beta;
import com.google.api.client.util.Clock;
import com.google.api.client.util.Preconditions;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.PublicKey;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

/**
 * {@link Beta} 
* Thread-safe Google ID token verifier. * *

Call {@link #verify(IdToken)} to verify a ID token. Use the constructor {@link * #GoogleIdTokenVerifier(HttpTransport, JsonFactory)} for the typical simpler case if your * application has only a single instance of {@link GoogleIdTokenVerifier}. Otherwise, ideally you * should use {@link #GoogleIdTokenVerifier(GooglePublicKeysManager)} with a shared global instance * of the {@link GooglePublicKeysManager} since that way the Google public keys are cached. Sample * usage: * *

{@code
 * GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(transport, jsonFactory)
 *        .setAudience(Arrays.asList("myClientId"))
 *        .build();
 *
 * ...
 *
 * if (!verifier.verify(googleIdToken)) {...}
 * }
* * @since 1.7 */ @Beta public class GoogleIdTokenVerifier extends IdTokenVerifier { /** Google public keys manager. */ private final GooglePublicKeysManager publicKeys; /** * @param transport HTTP transport * @param jsonFactory JSON factory */ public GoogleIdTokenVerifier(HttpTransport transport, JsonFactory jsonFactory) { this(new Builder(transport, jsonFactory)); } /** * @param publicKeys Google public keys manager * @since 1.17 */ public GoogleIdTokenVerifier(GooglePublicKeysManager publicKeys) { this(new Builder(publicKeys)); } /** * @param builder builder * @since 1.14 */ protected GoogleIdTokenVerifier(Builder builder) { super(builder); publicKeys = builder.publicKeys; } /** * Returns the Google public keys manager. * * @since 1.17 */ public final GooglePublicKeysManager getPublicKeysManager() { return publicKeys; } /** * Returns the HTTP transport. * * @since 1.14 */ public final HttpTransport getTransport() { return publicKeys.getTransport(); } /** Returns the JSON factory. */ public final JsonFactory getJsonFactory() { return publicKeys.getJsonFactory(); } /** * Returns the public certificates encoded URL. * * @since 1.15 * @deprecated (scheduled to be removed in 1.18) Use {@link #getPublicKeysManager()} and {@link * GooglePublicKeysManager#getPublicCertsEncodedUrl()} instead. */ @Deprecated public final String getPublicCertsEncodedUrl() { return publicKeys.getPublicCertsEncodedUrl(); } /** * Returns the public keys. * *

Upgrade warning: in prior version 1.16 it may return {@code null} and not throw any * exceptions, but starting with version 1.17 it cannot return {@code null} and may throw {@link * GeneralSecurityException} or {@link IOException}. * * @deprecated (scheduled to be removed in 1.18) Use {@link #getPublicKeysManager()} and {@link * GooglePublicKeysManager#getPublicKeys()} instead. */ @Deprecated public final List getPublicKeys() throws GeneralSecurityException, IOException { return publicKeys.getPublicKeys(); } /** * Returns the expiration time in milliseconds to be used with {@link Clock#currentTimeMillis()} * or {@code 0} for none. * * @deprecated (scheduled to be removed in 1.18) Use {@link #getPublicKeysManager()} and {@link * GooglePublicKeysManager#getExpirationTimeMilliseconds()} instead. */ @Deprecated public final long getExpirationTimeMilliseconds() { return publicKeys.getExpirationTimeMilliseconds(); } /** * Verifies that the given ID token is valid using the cached public keys. * *

It verifies: * *

    *
  • The RS256 signature, which uses RSA and SHA-256 based on the public keys downloaded from * the public certificate endpoint. *
  • The current time against the issued at and expiration time (allowing for a 5 minute clock * skew). *
  • The issuer is {@code "accounts.google.com"} or {@code "https://accounts.google.com"}. *
* * @param googleIdToken Google ID token * @return {@code true} if verified successfully or {@code false} if failed */ public boolean verify(GoogleIdToken googleIdToken) throws GeneralSecurityException, IOException { // check the payload only if (!super.verifyPayload(googleIdToken)) { return false; } // verify signature, try all public keys in turn. for (PublicKey publicKey : publicKeys.getPublicKeys()) { if (googleIdToken.verifySignature(publicKey)) { return true; } } return false; } /** * Verifies that the given ID token is valid using {@link #verify(GoogleIdToken)} and returns the * ID token if succeeded. * * @param idTokenString Google ID token string * @return Google ID token if verified successfully or {@code null} if failed * @since 1.9 */ public GoogleIdToken verify(String idTokenString) throws GeneralSecurityException, IOException { GoogleIdToken idToken = GoogleIdToken.parse(getJsonFactory(), idTokenString); return verify(idToken) ? idToken : null; } /** * Downloads the public keys from the public certificates endpoint at {@link * #getPublicCertsEncodedUrl}. * *

This method is automatically called if the public keys have not yet been initialized or if * the expiration time is very close, so normally this doesn't need to be called. Only call this * method explicitly to force the public keys to be updated. * * @deprecated (scheduled to be removed in 1.18) Use {@link #getPublicKeysManager()} and {@link * GooglePublicKeysManager#refresh()} instead. */ @Deprecated public GoogleIdTokenVerifier loadPublicCerts() throws GeneralSecurityException, IOException { publicKeys.refresh(); return this; } /** * {@link Beta}
* Builder for {@link GoogleIdTokenVerifier}. * *

Implementation is not thread-safe. * * @since 1.9 */ @Beta public static class Builder extends IdTokenVerifier.Builder { /** Google public keys manager. */ GooglePublicKeysManager publicKeys; /** * @param transport HTTP transport * @param jsonFactory JSON factory */ public Builder(HttpTransport transport, JsonFactory jsonFactory) { this(new GooglePublicKeysManager(transport, jsonFactory)); } /** * @param publicKeys Google public keys manager * @since 1.17 */ public Builder(GooglePublicKeysManager publicKeys) { this.publicKeys = Preconditions.checkNotNull(publicKeys); setIssuers(Arrays.asList("accounts.google.com", "https://accounts.google.com")); } /** Builds a new instance of {@link GoogleIdTokenVerifier}. */ @Override public GoogleIdTokenVerifier build() { return new GoogleIdTokenVerifier(this); } /** * Returns the Google public keys manager. * * @since 1.17 */ public final GooglePublicKeysManager getPublicCerts() { return publicKeys; } /** Returns the HTTP transport. */ public final HttpTransport getTransport() { return publicKeys.getTransport(); } /** Returns the JSON factory. */ public final JsonFactory getJsonFactory() { return publicKeys.getJsonFactory(); } /** * Returns the public certificates encoded URL. * * @since 1.15 * @deprecated (scheduled to be removed in 1.18) Use {@link #getPublicCerts()} and {@link * GooglePublicKeysManager#getPublicCertsEncodedUrl()} instead. */ @Deprecated public final String getPublicCertsEncodedUrl() { return publicKeys.getPublicCertsEncodedUrl(); } /** * Sets the public certificates encoded URL. * *

The default value is {@link GoogleOAuthConstants#DEFAULT_PUBLIC_CERTS_ENCODED_URL}. * *

Overriding is only supported for the purpose of calling the super implementation and * changing the return type, but nothing else. * * @since 1.15 * @deprecated (scheduled to be removed in 1.18) Use {@link * GooglePublicKeysManager.Builder#setPublicCertsEncodedUrl(String)} instead. */ @Deprecated public Builder setPublicCertsEncodedUrl(String publicKeysEncodedUrl) { // TODO(yanivi): make publicKeys field final when this method is removed publicKeys = new GooglePublicKeysManager.Builder(getTransport(), getJsonFactory()) .setPublicCertsEncodedUrl(publicKeysEncodedUrl) .setClock(publicKeys.getClock()) .build(); return this; } @Override public Builder setIssuer(String issuer) { return (Builder) super.setIssuer(issuer); } /** @since 1.21.0 */ @Override public Builder setIssuers(Collection issuers) { return (Builder) super.setIssuers(issuers); } @Override public Builder setAudience(Collection audience) { return (Builder) super.setAudience(audience); } @Override public Builder setAcceptableTimeSkewSeconds(long acceptableTimeSkewSeconds) { return (Builder) super.setAcceptableTimeSkewSeconds(acceptableTimeSkewSeconds); } @Override public Builder setClock(Clock clock) { return (Builder) super.setClock(clock); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy