主题:单点登录

如何拿到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();  
}  
}  
}
相关推荐
假装我不帅1 小时前
asp.net framework从webform开始创建mvc项目
后端·asp.net·mvc
神仙别闹1 小时前
基于ASP.NET+SQL Server实现简单小说网站(包括PC版本和移动版本)
后端·asp.net
计算机-秋大田1 小时前
基于Spring Boot的船舶监造系统的设计与实现,LW+源码+讲解
java·论文阅读·spring boot·后端·vue
货拉拉技术2 小时前
货拉拉-实时对账系统(算盘平台)
后端
掘金酱2 小时前
✍【瓜分额外奖金】11月金石计划附加挑战赛-活动命题发布
人工智能·后端
代码之光_19802 小时前
保障性住房管理:SpringBoot技术优势分析
java·spring boot·后端
ajsbxi3 小时前
苍穹外卖学习记录
java·笔记·后端·学习·nginx·spring·servlet
颜淡慕潇3 小时前
【K8S问题系列 |1 】Kubernetes 中 NodePort 类型的 Service 无法访问【已解决】
后端·云原生·容器·kubernetes·问题解决
尘浮生4 小时前
Java项目实战II基于Spring Boot的光影视频平台(开发文档+数据库+源码)
java·开发语言·数据库·spring boot·后端·maven·intellij-idea
尚学教辅学习资料4 小时前
基于SpringBoot的医药管理系统+LW示例参考
java·spring boot·后端·java毕业设计·医药管理