紀錄驗證 Google 第三方登入傳入的RSA 256 JWT token 的程式碼
, 其官方網站有公開 Public key 的 JWK,
JWK網址是:https://www.googleapis.com/oauth2/v3/certs
有兩種驗證的方法:
首先是第一種,
1. 使用第三方 JWK 驗證相關的 Library 來做驗證 (不限只能驗證 google 的 JWT)。
範例如下:
Maven 的 pom.xml :
<dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</artifactId> <version>3.18.2</version> </dependency> <dependency> <groupId>com.auth0</groupId> <artifactId>jwks-rsa</artifactId> <version>0.20.0</version> </dependency>
可能會需要 javax.xml.bind 這個 lib,因為 jdk 8 以上沒有 jaxb 模塊,詳見: 真正解决方案:java.lang.NoClassDefFoundError: javax/xml/bind/DatatypeConverter
<!-- https://mvnrepository.com/artifact/javax.xml.bind/jaxb-api --> <dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> <version>2.3.0</version> </dependency>
Java:
package test;
import java.io.IOException;
import java.net.URL;
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import com.auth0.jwk.Jwk;
import com.auth0.jwk.JwkException;
import com.auth0.jwk.JwkProvider;
import com.auth0.jwk.UrlJwkProvider;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.DecodedJWT;
import net.sf.json.JSONObject;
public class JWTTest {
public static void main(String[] args) throws IOException, GeneralSecurityException, JwkException {
String token = "someGoogleJwtToken";
verifyToken(token);
}
public static verifyToken(String token) {
try {
DecodedJWT jwt = JWT.decode(token);
JwkProvider provider = new UrlJwkProvider(new URL("https://www.googleapis.com/oauth2/v3/certs"));
RSAPublicKey publicKey = (RSAPublicKey) provider.get(jwt.getKeyId()).getPublicKey();
Algorithm algorithm = Algorithm.RSA256(publicKey, null);
JWTVerifier verifier = JWT.require(algorithm)
// more validations if needed
.build();
jwt = verifier.verify(token);
System.out.println("User Id: " + jwt.getSubject());
System.out.println("Email: " + jwt.getClaim("email").asString());
} catch (Exception e) {
System.out.println("Exception in verifying " + e.toString());
}
}
}
再來是第二種,
2. 使用 Google 提供的 LIbrary 來做驗證。
範例如下:
Maven 的 pom.xml :
<dependency> <groupId>com.google.api-client</groupId> <artifactId>google-api-client</artifactId> <version>1.32.1</version> </dependency>
Java:
package test;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Collections;
import com.auth0.jwk.JwkException;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken.Payload;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.json.gson.GsonFactory;
public class GoogleJWTTest2 {
public static void main(String[] args) throws IOException, GeneralSecurityException, JwkException {
String token = "eyJhbGciOiJSUzI1NiIsImtpZCI6ImZjYmQ3ZjQ4MWE4MjVkMTEzZTBkMDNkZDk0ZTYwYjY5ZmYxNjY1YTIiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJuYmYiOjE2NTE4MzA3OTQsImF1ZCI6Ijk2MjE1NTMyNDMyMy1vY3U5MzNkazFiYzY0dGhkM3JrdnVsaXI5MHVya3Nuby5hcHBzLmdvb2dsZXVzZXJjb250ZW50LmNvbSIsInN1YiI6IjEwMjA1NTY1MzA0MDM0ODc0MzExMyIsImVtYWlsIjoiaHVnb2dvNzY0NkBnbWFpbC5jb20iLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiYXpwIjoiOTYyMTU1MzI0MzIzLW9jdTkzM2RrMWJjNjR0aGQzcmt2dWxpcjkwdXJrc25vLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwibmFtZSI6IumDreeAmumahiIsInBpY3R1cmUiOiJodHRwczovL2xoMy5nb29nbGV1c2VyY29udGVudC5jb20vYS0vQU9oMTRHaExOWHdxT2l2cXAyOHdRY3lNZ3FGZERUU0dyYW1sSDQwTDRTejEzZz1zOTYtYyIsImdpdmVuX25hbWUiOiLngJrpmoYiLCJmYW1pbHlfbmFtZSI6IumDrSIsImlhdCI6MTY1MTgzMTA5NCwiZXhwIjoxNjUxODM0Njk0LCJqdGkiOiJmZDFlY2VmMThiNzAyZDIyNzQwNjRjZjdmMzMwOTExZDBlYzQ4NDI0In0.OFc3-NIiSsChOJWgF_SJZ9yWhSpAhY95PSllh7gSqS8YYiBJD6DIZCvbHnL2SLU69lv2kntoR-hG1aQU07ppgGN5xuqJAagvKJ8KSSkxJxSR5qOLFNMBYPghp0zgFybNEAQDTbj3E5zRlemX7w9irEMqkMliRAMDYE3aUkcOrho9X2vd9wJDrkwKmMaLfXa71MVPwIYpsOrg2Gq82nHLw24eM47VRTp3m1sqXdKz9WHgfW2_2y9GB0qn3E8Fo99wBgegRyAlz6UvbTzDNQOUdrvuSALXcrOZzog5rrfW0MinxdVfRbSNRKL0VGMJWzuGefxNqEV-Fu0CTPIqliXf1A";
verifyToken(token);
}
public static boolean verifyToken(String token) {
try {
GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(
GoogleNetHttpTransport.newTrustedTransport(), new GsonFactory())
// Specify the CLIENT_ID of the app that accesses the backend:
// .setAudience(Collections.singletonList(
// "962155324323-ocu933dk1bc64thd3rkvulir90urksno.apps.googleusercontent.com"))
// Or, if multiple clients access the backend:
// .setAudience(Arrays.asList(CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3))
.build();
// (Receive idTokenString by HTTPS POST)
GoogleIdToken idToken = verifier.verify(token);
if (idToken != null) {
Payload payload = idToken.getPayload();
// Print user identifier
String userId = payload.getSubject();
System.out.println("User ID: " + userId);
// Get profile information from payload
String email = payload.getEmail();
boolean emailVerified = Boolean.valueOf(payload.getEmailVerified());
String name = (String) payload.get("name");
String pictureUrl = (String) payload.get("picture");
String locale = (String) payload.get("locale");
String familyName = (String) payload.get("family_name");
String givenName = (String) payload.get("given_name");
System.out.println(email);
// Use or store profile information
// ...
} else {
System.out.println("Invalid ID token.");
}
return true;
} catch (Exception e) {
System.out.println("Exception in verifying " + e.toString());
return false;
}
}
}
沒有留言 :
張貼留言