痛苦!
由于来自Kerberos代码深处的异常,我尝试通过SSO使用Spring Security 5和Kerberos验证用户的尝试失败。我将首先显示堆栈跟踪和引起它的代码,然后提供有关我的环境的其他信息,这可能有助于消除某些可能性。
ConstraintLayout
因此,当我的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]
正在验证SSO票证时,有一个BadCredentialsException
。这只是抛出来自
SunJaasKerberosTicketValidator
PrivilegedActionException
}
public 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: null
方法是
PrivilegedActionException.toString
因此,public String toString() {
String s = getClass().getName();
return (exception != null) ? (s + ": " + exception.toString()) : s;
}
(原因异常)不为null,但是它以exception
...
但是,堆栈跟踪告诉我们问题的根源是来自Krb5AcceptCredential类的null
。
GSSException
if (creds == null)
throw new GSSException(GSSException.NO_CRED, -1,"Failed to find any Kerberos credentails");
是因为creds == null
(请参阅implementation)返回Krb5Util.getServiceCreds
而没有引起异常。
这是我到目前为止所走的路。现在,一些其他信息。
null
这是将抛出 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'
的对象的配置。
BadCredentialsException
我有能力证明我公司的SSO基础架构正常运行。同一台服务器正在运行另一个应用程序(带有Kerberos的Spring Security 4),可以通过SSO成功验证用户身份。因此,我的设置很可能有问题。
顺便说一下,我使用的是Chrome,但我也通过IE对其进行了测试。
如果您需要我的 KerberosServiceAuthenticationProvider provider = new KerberosServiceAuthenticationProvider();
provider.setTicketValidator(sunJaasKerberosTicketValidator());
provider.setUserDetailsService(myUserDetailService);
provider.supports(KerberosServiceRequestToken.class);
或其他信息,我会提供。愿力量与您同在:-)
这是我到目前为止发现的,但是这些示例略有不同。
WebSecurityConfig
BadCredentialsException
答案 0 :(得分:1)
我遇到这个问题已经 2 年了,但我记得,我解决了它......但忘记在这里发布解决方案(我的错)。由于这个问题得到了一些新的关注,我会尽力记住。
我挖出了代码,我想我记住了这个问题。在 WebSecurityConfig 中有一些方法注释为 @Bean
- 并且缺少一个。
我认为是 SunJaasKerberosTicketValidator
。它在此类中用于配置 KerberosServiceAuthenticationProvider
,但 Spring Security 似乎也在内部使用该 Bean - 如果 Spring 上下文中缺少该 Bean,则会失败。
这是我当时代码的(缩短的)版本。如果您也有 @Bean
注释的所有方法,请检查它们。
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(myUserDetailsService).passwordEncoder(passwordEncoder());
auth.authenticationProvider(kerberosServiceAuthenticationProvider());
}
@Override
public void configure(WebSecurity web) {
// ...
}
@Override
protected void configure(HttpSecurity http) throws Exception {
//...
}
@Bean
public SpnegoEntryPoint spnegoEntryPoint() {
//...
}
private KerberosServiceAuthenticationProvider kerberosServiceAuthenticationProvider() {
KerberosServiceAuthenticationProvider provider = new KerberosServiceAuthenticationProvider();
provider.setTicketValidator(ticketValidator());
provider.setUserDetailsService(myUserDetailsService);
return provider;
}
@Bean
public SpnegoAuthenticationProcessingFilter spnegoAuthenticationProcessingFilter() {
SpnegoAuthenticationProcessingFilter filter = new SpnegoAuthenticationProcessingFilter();
AuthenticationFailureHandler failureHandler =
new SimpleUrlAuthenticationFailureHandler(AUTHENTIFICATION_FAILED_URL);
filter.setFailureHandler(failureHandler);
try {
filter.setAuthenticationManager(authenticationManagerBean());
} catch (Exception e) {
throw new IllegalStateException(e);
}
return filter;
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public SunJaasKerberosTicketValidator ticketValidator() {
SunJaasKerberosTicketValidator ticketValidator = new SunJaasKerberosTicketValidator();
ticketValidator.setDebug(true);
ticketValidator.setServicePrincipal(kerberosConfigMgmt.securityKerberosServicePrincipal());
FileSystemResource fs = new FileSystemResource(kerberosConfigMgmt.securityKerberosKeyTapFileAbsolutePath());
ticketValidator.setKeyTabLocation(fs);
return ticketValidator;
}
@Bean(name = "authenticationSuccessHandler")
public AuthenticationSuccessHandler authenticationSuccessHandler() {
return new SimpleUrlAuthenticationSuccessHandler(STARTSEITE_URL);
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}