验证Azure AD生成的令牌时出现错误。这是当前设置:
我有一个可以粘贴在https://jwt.io上的令牌,并且在右侧面板中可以看到正确的声明。我认为令牌的格式正确。我还可以在标题中看到kid = piVlloQDSMKxh1m2ygqGSVdgFpA
和alg: RS256
。我将算法类型正确设置为RS256以进行验证。
我去了https://login.microsoftonline.com/common/discovery/keys查找公钥,并找到了相同的kid = piVlloQDSMKxh1m2ygqGSVdgFpA
。因此,我复制了相应的公钥(x5c
字段中的字符串),并将其包装到正确的字符串中以使其成为PKCS#8。兼容:
-----开始证书-----MIIDBTCCAe2gAwIBAgIQMCJcgWf4l5xPpeoEwB7DKDANBgkqhkiG9w0BAQsFADAtMSswKQYDVQQDEyJhY2NvdW50cy5hY2Nlc3Njb250cm9sLndpbmRvd3MubmV0MB4XDTE5MTExNTAwMDAwMFoXDTI0MTExNDAwMDAwMFowLTErMCkGA1UEAxMiYWNjb3VudHMuYWNjZXNzY29udHJvbC53aW5kb3dzLm5ldDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANF4YcKZhKTfowwWqZ84RW7bxFNgaSy3Gi85V5uJpU9jMCmZV0VFGptryNFEQ1GESmmuDutgQlkkhjr9ixkOrTA + aFPg6pLn + OG6NYS7nyKgAC1MprLH0bq06y3dH6lQPWQhd3wPP + 8UIua9 + 9JuIfhu9Xs / HhN5cYlT5cEniV0aWuUMxgPAKcG1xolfupYhlOHjFwVN / QOaxcuk3YqGguD + sZ7PiHcJSzFnTkdvD + DtMoW1U6nDf5FuDeAEKJ7JQf7RjiRoViYxZHKrEPHG4iZ + kOhV6DQA16ISTt7ALXVB8gTTF3OvItubk2E3v6sgirgtvdE5Mkd4MTJcO67bgdUCAwEAAaMhMB8wHQYDVR0OBBYEFEXiTeLGkA2LgAjQOrT2KChpgwCgMA0GCSqGSIb3DQEBCwUAA4IBAQA6GqtYZDQzym0yxfL2NnlSbJP / lLhSQOqbPBdN6DWQ / 3duk + e08Ix5qy63hzW + qQR0PAkFEcooL5 + bdheS66tFJpVejEcqCSKUVvwOUe6GY / ju752dlB7anBB9An362khehCxqydYNS5Igl0rtcP7dKC3ZBn1m2B9ULsyx46iNpfHQHHv9NKU2vVq2CtNc95CFktwjUwlyWMgbfI / DzPX / cC6KnglqsuVVBO7 + jIaBmi0XGqudooZkqgIrvnfNMM13Gy78TUNHsCiAQEwZ / L17yNbzotNGxAoPfuXldbD52MQNOsA7 WhH + j8qFWY6gZzTN4NpVtuW4m04TCEFexnTz-----结束证书-----
如果上面不可见,则在\n
之后和-----BEGIN CERTIFICATE-----
之前有一个-----END CERTIFICATE-----
它一直无效。在jwt.io和我的代码中甚至都没有过期,显然是无效的。
假设令牌正确,我的方法正确吗?我发现准备.pem的不同教程有所不同。如果我的令牌不正确,除了从中获取索赔外,我该如何检查?
您需要从modulus
和exponent
生成公共密钥。
您可以从https://login.microsoftonline.com/{tenantId_or_commom}/discovery/v2.0/keys
中获得它们
这里是一个Java示例供您参考:
public static PublicKey getPublicKey(String encodedModulus, String encodedExponent) throws NoSuchAlgorithmException, InvalidKeySpecException {
byte[] modulus = Base64.getUrlDecoder().decode(encodedModulus);
byte[] exponent = Base64.getUrlDecoder().decode(encodedExponent);
StringBuilder sb = new StringBuilder();
for (byte b : modulus) {
sb.append(String.format("%02x", b));
}
String sm = sb.toString();
sb = new StringBuilder();
for (byte b : exponent) {
sb.append(String.format("%02x", b));
}
String se = sb.toString();
BigInteger bm = new BigInteger(sm,16);
BigInteger be = new BigInteger(se,16);
KeyFactory rsa = KeyFactory.getInstance("RSA");
PublicKey publicKey = rsa.generatePublic(new RSAPublicKeySpec(bm, be));
return publicKey;
}
public static void main(String[] args) throws Exception {
String modulus = "0XhhwpmEpN-jDBapnzhFbtvEU2BpLLcaLzlXm4mlT2MwKZlXRUUam2vI0URDUYRKaa4O62BCWSSGOv2LGQ6tMD5oU-Dqkuf44bo1hLufIqAALUymssfRurTrLd0fqVA9ZCF3fA8_7xQi5r370m4h-G71ez8eE3lxiVPlwSeJXRpa5QzGA8ApwbXGiV-6liGU4eMXBU39A5rFy6TdioaC4P6xns-IdwlLMWdOR28P4O0yhbVTqcN_kW4N4AQonslB_tGOJGhWJjFkcqsQ8cbiJn6Q6FXoNADXohJO3sAtdUHyBNMXc68i25uTYTe_qyCKuC290TkyR3gxMlw7rtuB1Q";
String exponent = "AQAB";
byte[] bytes = getPublicKey(modulus, exponent).getEncoded();
String encodedString = new String(Base64.getEncoder().encode(bytes));
System.out.println("-----BEGIN PUBLIC KEY-----");
System.out.println(encodedString);
System.out.println("-----END PUBLIC KEY-----");
System.out.println();
}
您将获得以下输出:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0XhhwpmEpN+jDBapnzhFbtvEU2BpLLcaLzlXm4mlT2MwKZlXRUUam2vI0URDUYRKaa4O62BCWSSGOv2LGQ6tMD5oU+Dqkuf44bo1hLufIqAALUymssfRurTrLd0fqVA9ZCF3fA8/7xQi5r370m4h+G71ez8eE3lxiVPlwSeJXRpa5QzGA8ApwbXGiV+6liGU4eMXBU39A5rFy6TdioaC4P6xns+IdwlLMWdOR28P4O0yhbVTqcN/kW4N4AQonslB/tGOJGhWJjFkcqsQ8cbiJn6Q6FXoNADXohJO3sAtdUHyBNMXc68i25uTYTe/qyCKuC290TkyR3gxMlw7rtuB1QIDAQAB
-----END PUBLIC KEY-----