Spring Boot 3.3.0集成Azure AD SAML SSO:证书验证咨询
关于Spring Boot 3.3.0 + Azure AD SAML SSO的证书验证问题
一、确认SAML响应是否使用Azure配置的证书验证
1. 通过日志排查
Spring Security SAML2默认会自动验证SAML响应的签名,开启DEBUG级别日志可以直接查看验证过程及使用的证书信息:
在application.properties中添加日志配置:
logging.level.org.springframework.security.saml2=DEBUG logging.level.org.opensaml=DEBUG
登录成功后,查看日志会包含类似以下信息:
验证SAML响应签名成功,使用证书指纹: [SHA-256指纹值]
你可以将这个指纹和Azure AD应用中配置的证书指纹对比,确认是否一致。
2. 自定义逻辑获取验证证书
你可以在自定义的customSAMLAuthenticationHandler中,从认证令牌里提取实际用于验证的证书,代码示例如下:
@Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { if (authentication instanceof Saml2AuthenticationToken) { Saml2AuthenticationToken samlToken = (Saml2AuthenticationToken) authentication; Saml2Response samlResponse = samlToken.getSaml2Response(); X509Certificate signingCert = samlResponse.getVerificationCertificate(); // 生成证书SHA-256指纹 String fingerprint = generateSha256Fingerprint(signingCert); System.out.println("验证SAML响应的证书指纹: " + fingerprint); // 此处可将指纹与Azure配置的证书指纹做对比 } // 后续跳转或业务逻辑处理 } private String generateSha256Fingerprint(X509Certificate cert) throws NoSuchAlgorithmException { MessageDigest md = MessageDigest.getInstance("SHA-256"); byte[] digest = md.digest(cert.getEncoded()); StringBuilder sb = new StringBuilder(); for (byte b : digest) { sb.append(String.format("%02x", b)).append(":"); } return sb.deleteCharAt(sb.length() - 1).toString(); }
二、验证Azure AD应用中Base64格式的证书
1. 提取并解析Base64证书
从Azure AD应用的SAML签名证书中复制Base64内容(可保留或去除首尾的-----BEGIN CERTIFICATE-----/-----END CERTIFICATE-----标记),通过以下代码解析为X509证书并验证:
import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.io.ByteArrayInputStream; import java.util.Base64; import java.security.MessageDigest; public class AzureCertValidator { public static void main(String[] args) throws Exception { // 替换为Azure获取的Base64证书内容 String azureBase64Cert = "你的Azure Base64证书字符串"; // 清理证书内容中的换行和标记 String cleanedCert = azureBase64Cert.replaceAll("-----BEGIN CERTIFICATE-----", "") .replaceAll("-----END CERTIFICATE-----", "") .replaceAll("\\s+", ""); // 解析为X509证书 byte[] certBytes = Base64.getDecoder().decode(cleanedCert); CertificateFactory cf = CertificateFactory.getInstance("X.509"); X509Certificate cert = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(certBytes)); // 验证证书有效性 cert.checkValidity(); // 检查当前时间是否在证书有效期内 System.out.println("证书有效期起始: " + cert.getNotBefore()); System.out.println("证书有效期结束: " + cert.getNotAfter()); System.out.println("证书颁发者: " + cert.getIssuerDN()); System.out.println("证书SHA-256指纹: " + generateSha256Fingerprint(cert)); } private static String generateSha256Fingerprint(X509Certificate cert) throws NoSuchAlgorithmException { MessageDigest md = MessageDigest.getInstance("SHA-256"); byte[] digest = md.digest(cert.getEncoded()); StringBuilder sb = new StringBuilder(); for (byte b : digest) { sb.append(String.format("%02x", b)).append(":"); } return sb.deleteCharAt(sb.length() - 1).toString(); } }
2. 对比确认
将解析出的Azure证书指纹,和之前从SAML响应中获取的验证证书指纹对比,若一致则说明SAML响应确实使用了你在Azure配置的证书进行验证。
内容的提问来源于stack exchange,提问作者Raghu
相关产品推荐
相关产品推荐

