aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/com/github
diff options
context:
space:
mode:
authorGravatar Vitaly Takmazov2021-04-12 19:09:44 +0300
committerGravatar Vitaly Takmazov2021-04-12 19:09:44 +0300
commitdeb873a5f4ea6429fa5974c0dfe62b9e0544d9fb (patch)
tree2b26f90cdfcd36b6d50bbcf33f55682b34ad1419 /src/main/java/com/github
parent8a4691ce820d26943a33095055c372461ae3bad6 (diff)
Verify Google JWT tokens without Google libraries
Diffstat (limited to 'src/main/java/com/github')
-rw-r--r--src/main/java/com/github/scribejava/apis/GoogleTokenVerifier.java66
1 files changed, 66 insertions, 0 deletions
diff --git a/src/main/java/com/github/scribejava/apis/GoogleTokenVerifier.java b/src/main/java/com/github/scribejava/apis/GoogleTokenVerifier.java
new file mode 100644
index 00000000..35a9d832
--- /dev/null
+++ b/src/main/java/com/github/scribejava/apis/GoogleTokenVerifier.java
@@ -0,0 +1,66 @@
+package com.github.scribejava.apis;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.text.ParseException;
+import java.util.Map;
+import java.util.Optional;
+
+import com.nimbusds.jose.JOSEException;
+import com.nimbusds.jose.JWSAlgorithm;
+import com.nimbusds.jose.jwk.source.JWKSource;
+import com.nimbusds.jose.jwk.source.RemoteJWKSet;
+import com.nimbusds.jose.proc.BadJOSEException;
+import com.nimbusds.jose.proc.JWSKeySelector;
+import com.nimbusds.jose.proc.JWSVerificationKeySelector;
+import com.nimbusds.jose.proc.SecurityContext;
+import com.nimbusds.jwt.proc.ConfigurableJWTProcessor;
+import com.nimbusds.jwt.proc.DefaultJWTClaimsVerifier;
+import com.nimbusds.jwt.proc.DefaultJWTProcessor;
+
+public class GoogleTokenVerifier {
+
+ public static Optional<String> validateToken(String idToken) {
+
+ // Create a JWT processor for the access tokens
+ ConfigurableJWTProcessor<SecurityContext> jwtProcessor =
+ new DefaultJWTProcessor<>();
+
+ // The public RSA keys to validate the signatures will be sourced from the
+ // OAuth 2.0 server's JWK set, published at a well-known URL. The RemoteJWKSet
+ // object caches the retrieved keys to speed up subsequent look-ups and can
+ // also handle key-rollover
+ JWKSource<SecurityContext> keySource =
+ null;
+ try {
+ keySource = new RemoteJWKSet<>(new URL("https://www.googleapis.com/oauth2/v3/certs"));
+ } catch (MalformedURLException e) {
+ return Optional.empty();
+ }
+
+ // The expected JWS algorithm of the access tokens (agreed out-of-band)
+ JWSAlgorithm expectedJWSAlg = JWSAlgorithm.RS256;
+
+ // Configure the JWT processor with a key selector to feed matching public
+ // RSA keys sourced from the JWK set URL
+ JWSKeySelector<SecurityContext> keySelector =
+ new JWSVerificationKeySelector<>(expectedJWSAlg, keySource);
+
+ jwtProcessor.setJWSKeySelector(keySelector);
+
+ // Set the required JWT claims for access tokens issued by the server
+ jwtProcessor.setJWTClaimsSetVerifier(new DefaultJWTClaimsVerifier<>());
+
+ // Process the token
+ Map<String, Object> claimsSet;
+ try {
+ claimsSet = jwtProcessor.process(idToken, null).toJSONObject();
+ } catch (BadJOSEException | JOSEException | ParseException e) {
+ return Optional.empty();
+ }
+
+ String email = (String)claimsSet.get("email");
+ boolean verified = claimsSet.get("email_verified").equals(true);
+ return verified ? Optional.of(email) : Optional.empty();
+ }
+}