【发布时间】:2019-10-02 09:18:31
【问题描述】:
Moin!
我尝试使用 Spring Security 5 和 Kerberos 通过 SSO 对用户进行身份验证失败,原因是来自 Kerberos 代码深处的异常。我将首先显示堆栈跟踪和导致它的代码,然后提供有关我的环境的其他信息,这可能有助于消除一些可能性。
堆栈跟踪
WARN 3932 --- [apr-8080-exec-1] w.a.SpnegoAuthenticationProcessingFilter : Negotiate Header was invalid: Negotiate YIILSwYGKwYBBQUCoIILPzCCCzugMDAuBgkqhkiC9xIBAgIGCSqGSIb3EgECAgYKKwYBBAGCN[and so on]
org.springframework.security.authentication.BadCredentialsException: Kerberos validation not successful
at org.springframework.security.kerberos.authentication.sun.SunJaasKerberosTicketValidator.validateTicket(SunJaasKerberosTicketValidator.java:71) ~[spring-security-kerberos-core-1.0.1.RELEASE.jar:1.0.1.RELEASE]
at org.springframework.security.kerberos.authentication.KerberosServiceAuthenticationProvider.authenticate(KerberosServiceAuthenticationProvider.java:64) ~[spring-security-kerberos-core-1.0.1.RELEASE.jar:1.0.1.RELEASE]
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:174) ~[spring-security-core-5.1.1.RELEASE.jar:5.1.1.RELEASE]
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:199) ~[spring-security-core-5.1.1.RELEASE.jar:5.1.1.RELEASE]
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$AuthenticationManagerDelegator.authenticate(WebSecurityConfigurerAdapter.java:512) ~[spring-security-config-5.1.1.RELEASE.jar:5.1.1.RELEASE]
...
Caused by: java.security.PrivilegedActionException: null
at java.security.AccessController.doPrivileged(Native Method) ~[na:1.8.0_162]
at javax.security.auth.Subject.doAs(Subject.java:422) ~[na:1.8.0_162]
at org.springframework.security.kerberos.authentication.sun.SunJaasKerberosTicketValidator.validateTicket(SunJaasKerberosTicketValidator.java:68) ~[spring-security-kerberos-core-1.0.1.RELEASE.jar:1.0.1.RELEASE]
...
Caused by: org.ietf.jgss.GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos credentails)
at sun.security.jgss.krb5.Krb5AcceptCredential.getInstance(Krb5AcceptCredential.java:87) ~[na:1.8.0_162]
at sun.security.jgss.krb5.Krb5MechFactory.getCredentialElement(Krb5MechFactory.java:127) ~[na:1.8.0_162]
at sun.security.jgss.krb5.Krb5MechFactory.getMechanismContext(Krb5MechFactory.java:198) ~[na:1.8.0_162]
-
所以有一个
的BadCredentialsException,而我的SunJaasKerberosTicketValidator正在验证 SSO 票证。这只是重新抛出来自PrivilegedActionExceptionpublic KerberosTicketValidation validateTicket(byte[] token) { try { return Subject.doAs(this.serviceSubject, new KerberosValidateAction(token)); } catch (PrivilegedActionException e) { throw new BadCredentialsException("Kerberos validation not successful", e); }}
-
PrivilegedActionException来自native方法java.security.AccessController.doPrivileged,因此很难跟踪。我不知道实施。 我觉得有趣是PrivilegedActionException打印为Caused by: java.security.PrivilegedActionException: nullPrivilegedActionException.toString方法是public String toString() { String s = getClass().getName(); return (exception != null) ? (s + ": " + exception.toString()) : s; }所以
exception(原因异常)不为空,但打印为null... -
但是堆栈跟踪告诉我们问题的根源是来自Krb5AcceptCredential类的
GSSException。if (creds == null) throw new GSSException(GSSException.NO_CRED, -1,"Failed to find any Kerberos credentails");而
creds == null是因为Krb5Util.getServiceCreds(参见implementation)返回null而不会导致异常。
这是我到现在为止的距离。现在有一些额外的信息。
在我的 WebSecurityConfig 中创建票证验证器
SunJaasKerberosTicketValidator ticketValidator = new SunJaasKerberosTicketValidator();
ticketValidator.setServicePrincipal("HTTP/host@REALM");
FileSystemResource fs = new FileSystemResource("PATH_TO_KEYTAB");
ticketValidator.setKeyTabLocation(fs);
LOGGER.info(fs.exists()); // prints 'true'
创建 KerberosServiceAuthenticationProvider
这是将抛出BadCredentialsException的对象的配置。
KerberosServiceAuthenticationProvider provider = new KerberosServiceAuthenticationProvider();
provider.setTicketValidator(sunJaasKerberosTicketValidator());
provider.setUserDetailsService(myUserDetailService);
provider.supports(KerberosServiceRequestToken.class);
我知道 SSO 有效
我有幸能够证明我公司的 SSO 基础架构有效。同一台服务器正在运行另一个应用程序(带有 Kerberos 的 Spring Security 4),其中用户可以通过 SSO 成功进行身份验证。所以我的设置很可能有问题。
顺便说一下我用的是Chrome,不过我也用IE测试过。
如果您需要我的WebSecurityConfig 的其他信息或其他信息,我会提供。愿原力与你同在:-)
其他问题
这是我目前发现的,但这些示例略有不同。
-
GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)
- 其他错误信息
- 其他设置:我没有 krb5.conf 文件
-
BadCredentialsException: Kerberos validation not succesfull
- 导致
BadCredentialsException的其他根异常 - 从 2012 年开始
- 导致
-
Kerberos authentication not working with spring security
- 导致
BadCredentialsException的其他根异常
- 导致
【问题讨论】:
-
仍然不知道如何解决这个问题?
-
@Klapsa2503 - 如果您有同样的问题,提供 HTTP 请求和响应详细信息(包括标头等 - curl -v 等效项)非常有帮助。这些问题通常会突然出现,因为客户端没有在请求中首先发送 Curb 票证。有时它会退回到 NTLM,或者只是完全不添加票证。无论哪种方式,如果没有请求上下文,就不可能知道
标签: java spring spring-security single-sign-on spring-security-kerberos