如何拿到OAuth2单点登录的idToken进行校验
- 获取JWKS数据
- Base64解码
- 对idToken验证
pom引进jar包
xml
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>4.0.0</version>
</dependency>
main
java
package cn.xml.authentication;
import java.io.IOException;
import java.net.URL;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.Signature;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.X509EncodedKeySpec;
import java.text.ParseException;
import java.util.Base64;
import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.jwk.JWKSet;
import com.nimbusds.jose.jwk.RSAKey;
public class JwtTokenValidator {
public static boolean check(String publicKeyStr, String idToken) throws Exception {
// 将公钥字符串转换为PublicKey实例
byte[] publicBytes = Base64.getDecoder().decode(publicKeyStr);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(keySpec);
// 创建Signature实例并初始化它
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initVerify(publicKey);
String[] splitString = idToken.split("\\.");
String unsignedToken = splitString[0] + "." + splitString[1];
String signatureStr = splitString[2];
// 对签名进行Base64解码
byte[] signatureBytes = Base64.getUrlDecoder().decode(signatureStr);// 验证签名
signature.update(unsignedToken.getBytes());
boolean isVerified = signature.verify(signatureBytes);
if (isVerified) {
System.out.println("idToken的签名验证成功!");
return true;
} else {
System.out.println("idToken的签名验证失败!");
return false;
}
}
/**
* 根据链接地址获取轮询公钥
* @param uri
* @return
* @throws JOSEException
* @throws IOException
* @throws ParseException
*/
public static String getPublicKey(String uri) throws JOSEException, IOException,
ParseException {
// JWKS URL
URL jwksUrl = new URL(uri);
// 获取JWKS
JWKSet jwkSet = JWKSet.load(jwksUrl);
// 假设我们只关心第一个JWK
RSAKey rsaKey = (RSAKey) jwkSet.getKeys().get(0);
// 转换为RSAPublicKey
RSAPublicKey rsaPublicKey = rsaKey.toRSAPublicKey();
// 获取公钥的编码字节
byte[] publicKeyEncoded = rsaPublicKey.getEncoded();
return Base64.getEncoder().encodeToString(publicKeyEncoded);
}
public static void main(String[] args) {
try {
// 使用Base64编码这些字节
String publicKeyBase64 = JwtTokenValidator.getPublicKey(
"https://abc.com/oidc/jwks");
String idToken = "eyJraWQiOiIxMjQyNzkwNTgxNDQxNDIxMzEyIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiIxMjE3MzMyODY1ODMxMDQ3MTY4IiwiZW1haWxfdmVyaWZpZWQiOnRydWUsImlzcyI6Imh0dHBzOi8vcG9ydGFsLmthaWtlYmFuZy52aXAvYXBpL3YxL2F1dGhvcml6ZS9xeXVrYml0NnV4cHFrZmtqdGFlenhraGx2aGlocWZ5ZS9vaWRjIiwicHJlZmVycmVkX3VzZXJuYW1lIjoiY2hlbmciLCJwaWN0dXJlIjoiaHR0cHM6Ly9hcGkubXVsdGlhdmF0YXIuY29tL1gyanJyVi5zdmciLCJzaWQiOiJxOTFhTDFrbXRzcExGWWFWVHhaYkN3c0otSjlnU09yM08zanhpeFlHLWk4IiwiYXVkIjoiZGMxNDEyYjMzMDAyNzdlNDczMjlhODJhZWE5NzM5NTMiLCJ1cGRhdGVkX2F0IjoiMjAyNC0wMy0xMyAxMjo0NjoxMiIsImF6cCI6ImRjMTQxMmIzMzAwMjc3ZTQ3MzI5YTgyYWVhOTczOTUzIiwiYXV0aF90aW1lIjoxNzE3ODYyOTE4LCJuaWNrbmFtZSI6IuWkp-a8oOWtpOm5sOeoiyIsImV4cCI6MTcxNzg2NDc0MSwiaWF0IjoxNzE3ODYyOTQxLCJlbWFpbCI6IjEzNjAxMTQ1NjExQDEzOTAuY29tIn0.EMgK8z5ey7bIHAB2YQ1UL9XVeieC2Lb1FWsWSHas7AHnDlX2kZWI6rZ3JKcpZnBj7zs_7hyU4I8zwRIUmr5DN7xjDgXUviQ1RtFcpeJ9eCqqdQ4ykGM1u4BuQJh6N32fPHZyW40ITxQcU-Wr2PCHYISaOhQWmv6qgBawuIktIJBifudPFIPb54CGHI9PRD9TUoIdzINP9XOfeEUVHsPjb1A6loI8duUYy7UrgUXn8k_ofhG4-PrWUOxQWBiqx9X7hE4ucQXm1NEkKVxxyJ6w7C_MDck3Me0ACXyi7rVazYYSb0iMzH_8ksuqduzlk1H1ixjte5tAZUWPDkZvzMyv5Q";
JwtTokenValidator.check(publicKeyBase64, idToken);
} catch (Exception e) {
e.printStackTrace();
}
}
}