diff --git a/iap/pom.xml b/iap/pom.xml index 2560c8997d3..efe7b1a40f8 100644 --- a/iap/pom.xml +++ b/iap/pom.xml @@ -60,11 +60,6 @@ google-auth-library-oauth2-http 0.21.0 - - com.nimbusds - nimbus-jose-jwt - 8.19 - diff --git a/iap/src/main/java/com/example/iap/VerifyIapRequestHeader.java b/iap/src/main/java/com/example/iap/VerifyIapRequestHeader.java index 61503264456..5f894187cd9 100644 --- a/iap/src/main/java/com/example/iap/VerifyIapRequestHeader.java +++ b/iap/src/main/java/com/example/iap/VerifyIapRequestHeader.java @@ -18,53 +18,14 @@ // [START iap_validate_jwt] import com.google.api.client.http.HttpRequest; -import com.google.common.base.Preconditions; -import com.nimbusds.jose.JWSHeader; -import com.nimbusds.jose.JWSVerifier; -import com.nimbusds.jose.crypto.ECDSAVerifier; -import com.nimbusds.jose.jwk.ECKey; -import com.nimbusds.jose.jwk.JWK; -import com.nimbusds.jose.jwk.JWKSet; -import com.nimbusds.jwt.JWTClaimsSet; -import com.nimbusds.jwt.SignedJWT; -import java.net.URL; -import java.security.interfaces.ECPublicKey; -import java.time.Clock; -import java.time.Instant; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; +import com.google.api.client.json.webtoken.JsonWebToken; +import com.google.auth.oauth2.TokenVerifier; /** Verify IAP authorization JWT token in incoming request. */ public class VerifyIapRequestHeader { - private static final String PUBLIC_KEY_VERIFICATION_URL = - "https://www.gstatic.com/iap/verify/public_key-jwk"; - private static final String IAP_ISSUER_URL = "https://cloud.google.com/iap"; - // using a simple cache with no eviction for this sample - private final Map keyCache = new HashMap<>(); - - private static Clock clock = Clock.systemUTC(); - - private ECPublicKey getKey(String kid, String alg) throws Exception { - JWK jwk = keyCache.get(kid); - if (jwk == null) { - // update cache loading jwk public key data from url - JWKSet jwkSet = JWKSet.load(new URL(PUBLIC_KEY_VERIFICATION_URL)); - for (JWK key : jwkSet.getKeys()) { - keyCache.put(key.getKeyID(), key); - } - jwk = keyCache.get(kid); - } - // confirm that algorithm matches - if (jwk != null && jwk.getAlgorithm().getName().equals(alg)) { - return ECKey.parse(jwk.toJSONString()).toECPublicKey(); - } - return null; - } - // Verify jwt tokens addressed to IAP protected resources on App Engine. // The project *number* for your Google Cloud project via 'gcloud projects describe $PROJECT_ID' // The project *number* can also be retrieved from the Project Info card in Cloud Console. @@ -96,38 +57,21 @@ boolean verifyJwtForComputeEngine( Long.toUnsignedString(projectNumber), Long.toUnsignedString(backendServiceId))); } - private boolean verifyJwt(String jwtToken, String expectedAudience) throws Exception { - - // parse signed token into header / claims - SignedJWT signedJwt = SignedJWT.parse(jwtToken); - JWSHeader jwsHeader = signedJwt.getHeader(); - - // header must have algorithm("alg") and "kid" - Preconditions.checkNotNull(jwsHeader.getAlgorithm()); - Preconditions.checkNotNull(jwsHeader.getKeyID()); - - JWTClaimsSet claims = signedJwt.getJWTClaimsSet(); - - // claims must have audience, issuer - Preconditions.checkArgument(claims.getAudience().contains(expectedAudience)); - Preconditions.checkArgument(claims.getIssuer().equals(IAP_ISSUER_URL)); - - // claim must have issued at time in the past - Date currentTime = Date.from(Instant.now(clock)); - Preconditions.checkArgument(claims.getIssueTime().before(currentTime)); - // claim must have expiration time in the future - Preconditions.checkArgument(claims.getExpirationTime().after(currentTime)); - - // must have subject, email - Preconditions.checkNotNull(claims.getSubject()); - Preconditions.checkNotNull(claims.getClaim("email")); - - // verify using public key : lookup with key id, algorithm name provided - ECPublicKey publicKey = getKey(jwsHeader.getKeyID(), jwsHeader.getAlgorithm().getName()); - - Preconditions.checkNotNull(publicKey); - JWSVerifier jwsVerifier = new ECDSAVerifier(publicKey); - return signedJwt.verify(jwsVerifier); + private boolean verifyJwt(String jwtToken, String expectedAudience) { + TokenVerifier tokenVerifier = TokenVerifier.newBuilder() + .setAudience(expectedAudience) + .setIssuer(IAP_ISSUER_URL) + .build(); + try { + JsonWebToken jsonWebToken = tokenVerifier.verify(jwtToken); + + // Verify that the token contain subject and email claims + JsonWebToken.Payload payload = jsonWebToken.getPayload(); + return payload.getSubject() != null && payload.get("email") != null; + } catch (TokenVerifier.VerificationException e) { + System.out.println(e.getMessage()); + return false; + } } } // [END iap_validate_jwt]