azure - 如何在 Java 中验证 Azure AD JWT 令牌?
问题描述
我有一个使用 Msal 库获得的 Azure AD JWT 令牌,但是当我尝试验证此令牌时出现问题:
客户端:Sharepoint Web 部件
const config = {
auth: {
clientId: "xxxxx",
authority: "https://login.microsoftonline.com/yyyyyy"
}
};
const myMSALObj = new UserAgentApplication(config);
let accessTokenRequest = {
scopes: ["user.read"],
loginHint: this.context.pageContext.user.loginName,
extraQueryParameters: {domain_hint: 'organizations'}
}
myMSALObj.acquireTokenSilent(accessTokenRequest).then(
function(accessTokenResponse) {
// Acquire token silent success
let accessToken = accessTokenResponse.accessToken;
我正在尝试从以下位置检索公钥: https ://login.microsoftonline.com/tenant-id/.well-known/openid-configuration但使用此公钥我永远无法重定向到:https://login。 microsoftonline.com/common/discovery/keys
在这种情况下,还有其他方法可以获取公钥吗?
服务器:验证
public PublicKey getPublicKeyFromParams(String e, String n){
byte[] modulusBytes = Base64.getUrlDecoder().decode(n);
BigInteger modulusInt = new BigInteger(1, modulusBytes);
byte[] exponentBytes = Base64.getUrlDecoder().decode(e);
BigInteger exponentInt = new BigInteger(1, exponentBytes);
KeyFactory keyFactory;
RSAPublicKeySpec publicSpec = new RSAPublicKeySpec(modulusInt, exponentInt);
try {
keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePublic(publicSpec);
} catch (NoSuchAlgorithmException | InvalidKeySpecException ex) {
ex.printStackTrace();
}
return null;
}
@Test
public void name() throws Exception {
String jwt = "xxxxxxx";
KeyPair keyPair = Keys.keyPairFor(SignatureAlgorithm.RS256);
String e = Base64.getUrlEncoder().encodeToString((((RSAPublicKeyImpl) keyPair.getPublic()).getPublicExponent()).toByteArray());
String n = Base64.getUrlEncoder().encodeToString((((RSAPublicKeyImpl) keyPair.getPublic()).getModulus()).toByteArray());
System.out.println("Public Key: " + Base64.getUrlEncoder().encodeToString(keyPair.getPublic().getEncoded()));
System.out.println("Public Key Exponent: " + e);
System.out.println("Public Key Modulus: " + n);
String jws = Jwts.builder().setSubject("pepe").signWith(keyPair.getPrivate()).compact();
System.out.println("Generated JWS:" + jws);
PublicKey publicKey = getPublicKeyFromParams(e, n);
Jwt parsedJWs = Jwts.parserBuilder().setSigningKey(publicKey).build().parse(jws);
System.out.println("Parsed JWS: " + parsedJWs);
publicKey = getPublicKeyFromParams(eValue, nValue);
System.out.println("Azure PublicKey fron n-e: " + publicKey);
CertificateFactory factory = CertificateFactory.getInstance("X.509");
Certificate cert = factory.generateCertificate(new ByteArrayInputStream(
DatatypeConverter.parseBase64Binary("cccccccccccccccccc")));
publicKey = cert.getPublicKey();
System.out.println("Azure PublicKey from x5c: " + publicKey);
Jwt jwtParsed = Jwts.parserBuilder().setSigningKey(publicKey).build().parse(jwt);
System.out.println(jwtParsed);
}
public static PublicKey getPublicKey(String key){
try{
byte[] byteKey = Base64.getDecoder().decode(key);
X509EncodedKeySpec X509publicKey = new X509EncodedKeySpec(byteKey);
KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePublic(X509publicKey);
}
catch(Exception e){
e.printStackTrace();
}
return null;
}
解决方案
通过此更改,验证工作正常。
let accessTokenRequest = {
scopes:["clientId/.default"],
loginHint: this.context.pageContext.user.loginName,
extraQueryParameters: {domain_hint: 'organizations'}
}
推荐阅读
- sql - 在多对多关系中查找只有一个匹配的元组
- javascript - 为 Internet Explorer 跳过包含 d3.js
- freeradius - 关于windows的freeradius服务器的查询
- grass - 无法在 GRASS GIS 中打开 .gxw 文件
- html - html h1 文本隐藏在 div 下
- javascript - 关于lighterHTML中的if语句
- spring-boot - 优雅关机失败
- c# - 使用 MSBuild 发布构建时,程序集名称添加目录名称作为前缀
- angular - [ng-class]用一个条件添加多个类
- python - 如何让 selenium 不断重新加载页面直到找到正确的 class_name?