Spring Boot集成Kerberos:Windows票据缓存实现SSO配置遇阻求助
解决Spring Boot集成Kerberos SSO时的服务主体/Keytab缺失问题
首先明确核心误区:Kerberos服务端(你的Spring Boot应用)必须配置服务主体(SPN)和Keytab才能验证客户端的票据,你混淆了Kerberos客户端和服务端的工作模式——客户端可以用Windows缓存的票据,但服务端需要自己的身份凭证来验证这些票据的合法性。以下是具体修复步骤:
1. 修正依赖版本(适配Spring Boot 3.3.2)
spring-security-kerberos 1.0.1.RELEASE版本较旧,适配Spring Security 5.x,而Spring Boot 3.3.2搭配的是Spring Security 6.x,建议升级到兼容版本:
<dependencies> <!-- Spring Boot Starter Security --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <!-- Spring Security Kerberos(适配Spring Security 6.x) --> <dependency> <groupId>org.springframework.security.kerberos</groupId> <artifactId>spring-security-kerberos-core</artifactId> <version>1.1.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.security.kerberos</groupId> <artifactId>spring-security-kerberos-web</artifactId> <version>1.1.2.RELEASE</version> </dependency> <!-- Thymeleaf for HTML templates --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> </dependencies>
2. 配置krb5.conf(Kerberos配置文件)
即使是Windows环境,Java也需要明确的KDC信息来完成Kerberos交互,创建krb5.conf(Windows下可命名为krb5.ini):
[libdefaults] default_realm = YOUR_DOMAIN.COM # 替换为你的AD域,大写 dns_lookup_kdc = true dns_lookup_realm = true ticket_lifetime = 24h renew_lifetime = 7d forwardable = true [realms] YOUR_DOMAIN.COM = { kdc = YOUR_DC_HOSTNAME.YOUR_DOMAIN.COM # 替换为你的域控制器主机名 admin_server = YOUR_DC_HOSTNAME.YOUR_DOMAIN.COM default_domain = YOUR_DOMAIN.COM } [domain_realm] .your_domain.com = YOUR_DOMAIN.COM your_domain.com = YOUR_DOMAIN.COM
3. 修正jaas.conf配置
服务端需要accept段配置(用于验证客户端票据),而不是仅initiate段(客户端发起请求用):
com.sun.security.jgss.krb5.accept { com.sun.security.auth.module.Krb5LoginModule required useKeyTab=true keyTab="C:/path/to/your/service.keytab" # 替换为你的Keytab文件路径 storeKey=true useTicketCache=false principal="HTTP/your-service-hostname.your-domain.com@YOUR_DOMAIN.COM"; # 替换为你的服务SPN }; com.sun.security.jgss.krb5.initiate { com.sun.security.auth.module.Krb5LoginModule required useTicketCache=true doNotPrompt=true renewTGT=true; };
注:服务SPN需要提前在AD中注册,并生成对应的Keytab文件(可使用
ktpass工具生成)。
4. 完善SecurityConfiguration配置
给SunJaasKerberosTicketValidator添加服务主体和Keytab配置:
@Bean public SunJaasKerberosTicketValidator sunJaasKerberosTicketValidator() { SunJaasKerberosTicketValidator ticketValidator = new SunJaasKerberosTicketValidator(); // 设置服务主体(和jaas.conf中的保持一致) ticketValidator.setServicePrincipal("HTTP/your-service-hostname.your-domain.com@YOUR_DOMAIN.COM"); // 设置Keytab路径,可放在resources目录下用ClassPathResource,或用绝对路径 ticketValidator.setKeyTabLocation(new ClassPathResource("service.keytab")); ticketValidator.setDebug(true); return ticketValidator; }
5. 配置JVM启动参数
在Eclipse的运行配置中添加以下VM参数,确保Kerberos配置文件被加载:
-Djava.security.auth.login.config=C:/path/to/jaas.conf -Djava.security.krb5.conf=C:/path/to/krb5.conf -Dsun.security.krb5.debug=true # 可选,开启调试日志排查问题
6. 获取Windows用户信息
在控制器中通过Authentication对象获取当前登录的Windows用户:
import org.springframework.security.core.Authentication; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class UserController { @GetMapping("/current-user") public String getCurrentUser(Authentication authentication) { // 获取Windows用户名(格式:DOMAIN\username 或 username@DOMAIN.COM) String username = authentication.getName(); return "当前登录Windows用户: " + username; } }
关键说明
- 服务端必须拥有自己的SPN和Keytab,这是Kerberos服务端验证客户端票据的核心凭证,无法省略。
- 客户端(浏览器)需要配置为自动发送Kerberos票据(IE/Edge默认在Intranet区域开启,Chrome需额外配置)。
内容的提问来源于stack exchange,提问作者gkeepa
相关产品推荐
相关产品推荐

