Spring Boot + Ldap / AD + Kerberos SSO : KrbCryptoException - Checksum failed

孤街浪徒 提交于 2019-12-24 18:59:12

问题


I am trying to implement SSO with Spring Boot, Ldap and kerberos. Where I got multiple errors of Checksum fail for different encryption type.

environment details:-

Machine : Windows 10

JDK Version : Oracle 1.8.0_144 (64 bit)

I appear to have hit a bit of a dead-end where I am not able to find any solution.

Here is what error I get when run

Added key: 17version: 5
Added key: 18version: 5
Added key: 23version: 5
Found unsupported keytype (3) for HTTP/host.test@EXAMPLE.COM
Found unsupported keytype (1) for HTTP/host.test@EXAMPLE.COM
>>> EType: sun.security.krb5.internal.crypto.Aes128CtsHmacSha1EType
2019-08-30 11:26:10.746  WARN 6640 --- [p-bio-80-exec-9] w.a.SpnegoAuthenticationProcessingFilter : Negotiate Header was invalid: Negotiate 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

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-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:199) ~[spring-security-core-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$AuthenticationManagerDelegator.authenticate(WebSecurityConfigurerAdapter.java:494) ~[spring-security-config-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.security.kerberos.web.authentication.SpnegoAuthenticationProcessingFilter.doFilter(SpnegoAuthenticationProcessingFilter.java:145) ~[spring-security-kerberos-web-1.0.1.RELEASE.jar:1.0.1.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) [spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200) [spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) [spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116) [spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]

Caused by: java.security.PrivilegedActionException: null
    at java.security.AccessController.doPrivileged(Native Method) ~[na:1.8.0_144]
    at javax.security.auth.Subject.doAs(Subject.java:422) ~[na:1.8.0_144]
    at org.springframework.security.kerberos.authentication.sun.SunJaasKerberosTicketValidator.validateTicket(SunJaasKerberosTicketValidator.java:68)

Caused by: org.ietf.jgss.GSSException: Failure unspecified at GSS-API level (Mechanism level: Checksum failed)
    at sun.security.jgss.krb5.Krb5Context.acceptSecContext(Krb5Context.java:856) ~[na:1.8.0_144]
    at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:342) ~[na:1.8.0_144]
    at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:285) ~[na:1.8.0_144]
    at sun.security.jgss.spnego.SpNegoContext.GSS_acceptSecContext(SpNegoContext.java:906) ~[na:1.8.0_144]
    at sun.security.jgss.spnego.SpNegoContext.acceptSecContext(SpNegoContext.java:556) ~[na:1.8.0_144]
    at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:342) ~[na:1.8.0_144]
    at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:285) ~[na:1.8.0_144]

Caused by: sun.security.krb5.KrbCryptoException: Checksum failed
    at sun.security.krb5.internal.crypto.Aes128CtsHmacSha1EType.decrypt(Aes128CtsHmacSha1EType.java:102) ~[na:1.8.0_144]
    at sun.security.krb5.internal.crypto.Aes128CtsHmacSha1EType.decrypt(Aes128CtsHmacSha1EType.java:94) ~[na:1.8.0_144]
    at sun.security.krb5.EncryptedData.decrypt(EncryptedData.java:175) ~[na:1.8.0_144]
    at sun.security.krb5.KrbApReq.authenticate(KrbApReq.java:281) ~[na:1.8.0_144]
    at sun.security.krb5.KrbApReq.<init>(KrbApReq.java:149) ~[na:1.8.0_144]
    at sun.security.jgss.krb5.InitSecContextToken.<init>(InitSecContextToken.java:108)

Caused by: java.security.GeneralSecurityException: Checksum failed
    at sun.security.krb5.internal.crypto.dk.AesDkCrypto.decryptCTS(AesDkCrypto.java:451) ~[na:1.8.0_144]

Keytab file I have generated from windows server where AD is available through this command -

ktpass /out test.keytab /mapuser ldap-read@EXAMPLE.COM /princ HTTP/host.test@EXAMPLE.COM /pass password /ptype KRB5_NT_PRINCIPAL /crypto All

Set SPN for the same user through

Setspn –A HTTP/host.test@EXAMPLE.COM ldap-read

Check keytab file through command

ktab -l -e -t -k "C:\Install\test.keytab"

and it's result

Keytab name: C:\Install\test.keytab
KVNO Timestamp      Principal
---- -------------- ---------------------------------------------------------------------
   5 1/1/70 5:30 AM http/host.test@example.com (1:DES CBC mode with CRC-32)
   5 1/1/70 5:30 AM http/host.test@example.com (3:DES CBC mode with MD5)
   5 1/1/70 5:30 AM http/host.test@example.com (23:RC4 with HMAC)
   5 1/1/70 5:30 AM http/host.test@example.com (18:AES256 CTS mode with HMAC SHA1-96)
   5 1/1/70 5:30 AM http/host.test@example.com (17:AES128 CTS mode with HMAC SHA1-96)

Also updated client and server settings of security option and marked check to allow encryption types

Here is security configuration java file

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {


@Value("${ldap.url}")
private String ldapUrl;
@Value("${ldap.manager.dn}")
private String ldapManagerDn;
@Value("${ldap.manager.password}")
private String ldapManagerPassword;
@Value("${ldap.user.searchbase}")
private String ldapUserSearchBase;
@Value("${app.service-principal}")
private String servicePrincipal;

@Autowired
private StaffService userService;
@Autowired
CustomAuthenticationProvider customAuthProvider;


@Override
protected void configure(HttpSecurity http) throws Exception {

http.csrf().disable().exceptionHandling().authenticationEntryPoint(spnegoEntryPoint())
    .and().authorizeRequests()
    .antMatchers("/signup","/logout").permitAll()
    .antMatchers("/","/login","/index","/index/**","/projects","/projects/**","/project")
        .fullyAuthenticated()
    .and()
    .formLogin().loginPage("/login")
    .defaultSuccessUrl("/index")
    .and()
    .logout().permitAll()
    .and().headers()
      .frameOptions()
         .sameOrigin()
    .and()
    .addFilterBefore(
    spnegoAuthenticationProcessingFilter(authenticationManagerBean()),
    BasicAuthenticationFilter.class);

}

@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception{

    auth.
    authenticationProvider(kerberosAuthenticationProvider())
    .authenticationProvider(kerberosServiceAuthenticationProvider());
}

    @Bean
    public KerberosAuthenticationProvider kerberosAuthenticationProvider() {
        KerberosAuthenticationProvider provider =
                new KerberosAuthenticationProvider();
        SunJaasKerberosClient client = new SunJaasKerberosClient();
        client.setDebug(true);
        provider.setKerberosClient(client);
        provider.setUserDetailsService(userService);
        return provider;
    }

     @Bean
    public SpnegoEntryPoint spnegoEntryPoint() {
        return new SpnegoEntryPoint("/login");
    }

@Bean
public SpnegoAuthenticationProcessingFilter spnegoAuthenticationProcessingFilter(
        AuthenticationManager authenticationManager) {
    SpnegoAuthenticationProcessingFilter filter =
            new SpnegoAuthenticationProcessingFilter();
    try {
        filter.setAuthenticationManager(authenticationManagerBean());
    } catch (Exception e) {
        e.printStackTrace();
    }
    return filter;
}

    @Bean
    public KerberosServiceAuthenticationProvider kerberosServiceAuthenticationProvider() {
        KerberosServiceAuthenticationProvider provider =
                new KerberosServiceAuthenticationProvider();
        provider.setTicketValidator(sunJaasKerberosTicketValidator());
        provider.setUserDetailsService(userService);
        return provider;
    }

    @Bean
    public SunJaasKerberosTicketValidator sunJaasKerberosTicketValidator() {
        SunJaasKerberosTicketValidator ticketValidator =
                new SunJaasKerberosTicketValidator();
        ticketValidator.setServicePrincipal(servicePrincipal);
        FileSystemResource fs = new FileSystemResource("C:/install/test.keytab");
        ticketValidator.setKeyTabLocation(fs);
        ticketValidator.setDebug(true);
        return ticketValidator;
    }

    @Bean
    public LdapTemplate ldapTemplate() throws Exception{
        LdapTemplate ldapTemplate = new LdapTemplate();
        ldapTemplate.setIgnorePartialResultException(true);
        ldapTemplate.setContextSource(kerberosLdapContextSource());
        return ldapTemplate;
    }

    @Bean
    public KerberosLdapContextSource kerberosLdapContextSource() {
        KerberosLdapContextSource contextSource = new KerberosLdapContextSource(ldapUrl);
        contextSource.setBase(ldapUserSearchBase);
        contextSource.setUserDn(ldapManagerDn);
        contextSource.setPassword(ldapManagerPassword);
        SunJaasKrb5LoginConfig loginConfig = new SunJaasKrb5LoginConfig();
        FileSystemResource fs = new FileSystemResource("C:/install/test.keytab");
        loginConfig.setKeyTabLocation(fs);
        loginConfig.setServicePrincipal(servicePrincipal);
        loginConfig.setDebug(true);
        loginConfig.setUseTicketCache(true);
        loginConfig.setIsInitiator(true);
        contextSource.setLoginConfig(loginConfig);
        return contextSource;
    }

    @Bean
    public LdapUserDetailsService ldapUserDetailsService() {
        FilterBasedLdapUserSearch userSearch =
                new FilterBasedLdapUserSearch(ldapUserSearchBase, ldapUserSearchFilter, kerberosLdapContextSource());
        LdapUserDetailsService service = new LdapUserDetailsService(userSearch);
        CustomLdapUserDetailsMapper customLdapUserDetailsMapper = new CustomLdapUserDetailsMapper();
        service.setUserDetailsMapper(customLdapUserDetailsMapper);
        return service;
    }

    @Bean
    public BCryptPasswordEncoder passwordEncoder() {        
        return new BCryptPasswordEncoder();
    }

    @Bean
    public RestTemplate restTemplate() {
        FileSystemResource fs = new FileSystemResource("C:/install/test.keytab");
        return new KerberosRestTemplate(fs.getPath(),servicePrincipal);
    }
}

Following is the content of the krb5.ini file that is at C:\Windows in Windows 10 machine :-

[libdefaults]
  forwardable = true
  dns_lookup_kdc = true
  dns_lookup_realm = true
  default_realm = BAUER.DE
  default_keytab_name = "C:\Install\test.keytab"

  default_tkt_enctypes = rc4-hmac aes256-cts aes128-cts des3-cbc-sha1 des-cbc-md5 des-cbc-crc
  default_tgs_enctypes = rc4-hmac aes256-cts aes128-cts des3-cbc-sha1 des-cbc-md5 des-cbc-crc
  permitted_enctypes   = rc4-hmac aes256-cts aes128-cts des3-cbc-sha1 des-cbc-md5 des-cbc-crc

[realms]
  EXAMPLE.COM = {
     kdc = host.test
  }

[domain_realm]
  .host.test = EXAMPLE.COM
  host.test  = EXAMPLE.COM

I have also updated the JCE jar files under C:\Program Files\Java\jre1.8.0_191\lib\security and C:\Program Files\Java\jdk1.8.0_144\jre\lib\security folders.

What should be done to overcome this exception? Is there any Java code needs to update or any cofiguration for kerberos needs to change. Does anyone have any ideas?

UPDATE 1:

A checksum issue is still available. However I see a new issue while I checked keytab file from JAVA JDK with kinit command,

I executed following command from server wihin JDK 1.8 bin directory

kinit -k -t "C:\Install\test.keytab" HTTP/host.test@EXAMPLE.COM

And got ICMP port Unreachable error

java.net.PortUnreachableException: ICMP Port Unreachable
        at java.net.DualStackPlainDatagramSocketImpl.socketReceiveOrPeekData(Native Method)
        at java.net.DualStackPlainDatagramSocketImpl.receive0(DualStackPlainDatagramSocketImpl.java:124)
        at java.net.AbstractPlainDatagramSocketImpl.receive(AbstractPlainDatagramSocketImpl.java:143)
        at java.net.DatagramSocket.receive(DatagramSocket.java:812)
        at sun.security.krb5.internal.UDPClient.receive(NetClient.java:206)
        at sun.security.krb5.KdcComm$KdcCommunication.run(KdcComm.java:411)
        at sun.security.krb5.KdcComm$KdcCommunication.run(KdcComm.java:364)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.security.krb5.KdcComm.send(KdcComm.java:348)
        at sun.security.krb5.KdcComm.sendIfPossible(KdcComm.java:253)
        at sun.security.krb5.KdcComm.send(KdcComm.java:229)
        at sun.security.krb5.KdcComm.send(KdcComm.java:200)

回答1:


Please check these (this is a copy from my other answer here) :

  1. User logged into domain account on OS.
  2. Proper config in your browser, see Spring documentation

E.g. for Internet Explorer:

E.3 Internet Explorer

Complete following steps to ensure that your Internet Explorer browser is enabled to perform Spnego authentication.

Open Internet Explorer.
Click Tools > Intenet Options > Security tab.
In Local intranet section make sure your server is trusted by i.e. adding it into a list.

Then you should check how your Authorization HTTP header value looks like and paste it here, because it is not in the question description. The best option would be to implement logging filter (e.g. based on this answer). This filter must be added before spnegoAuthenticationProcessingFilter, for example:

.addFilterBefore(serverRequestLoggingFilter(), WebAsyncManagerIntegrationFilter.class)

in your SecurityConfig.



来源:https://stackoverflow.com/questions/57726513/spring-boot-ldap-ad-kerberos-sso-krbcryptoexception-checksum-failed

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!