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

1

3

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/[email protected]
Found unsupported keytype (1) for HTTP/[email protected]
>>> 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 [email protected] /princ HTTP/[email protected] /pass password /ptype KRB5_NT_PRINCIPAL /crypto All

Set SPN for the same user through

Setspn –A HTTP/[email protected] 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/[email protected] (1:DES CBC mode with CRC-32)
   5 1/1/70 5:30 AM http/[email protected] (3:DES CBC mode with MD5)
   5 1/1/70 5:30 AM http/[email protected] (23:RC4 with HMAC)
   5 1/1/70 5:30 AM http/[email protected] (18:AES256 CTS mode with HMAC SHA1-96)
   5 1/1/70 5:30 AM http/[email protected] (17:AES128 CTS mode with HMAC SHA1-96)

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

enter image description here

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/[email protected]

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)
Bowel answered 30/8, 2019 at 12:10 Comment(8)
Could be a lot of things, including... "SPNEGO/REST: Kerberos is very strict about hostnames and DNS; this can somehow trigger the problem" steveloughran.gitbooks.io/kerberos_and_hadoop/content/sections/…Spacial
Is your client configured properly? If it is, paste the token from Authorization header sent by client.Merari
@Merari - I have updated client windows settings to allow different encryption types. Is any other configuration you know ? Also, I have noticed Negotiate Header was invalid. Can you check token is available into question where exception is generated ?Bowel
I'm not sure if i understand your question properly, i will add answer that my help us understand each other.Merari
The error I got when WWW-Authenticate: Negotiate - Negotiate Header was invalid: Negotiate YIIHvAYGKwYBBQUCoIIHsDCCB6ygMDAuBgkqhkiC9xIBAgIGCSqGSIb3EgECAgYKKwYBBAGCNwICHgYKKwYBBAGCNwICCqKCB3YEggdyYIIHbgYJKoZIhvcSAQICAQBuggddMIIHWaADAgEFoQMCAQ6iBwMFACAAAACjggWuYYIFqjCCBaagAwIBBaEKGwhCQVVFUi5ERaImMCSgAwIBAqEdMBsbBEhUVFAbE3NvYjJrY3BtdDEuYmF1ZXIuZGWjggVpMIIFZaADAgERoQMCAReiggVXBIIFU5tkaIUxlA+/pN16ChAwhzYcBOSmrwdGmBhsC9xgC/0jdYS/6Y0dblJq1h0IAZvQ4R8b5cUM+8YMlaLUGSEJUTnIEHK6If7068MUS3fA5MDyypCezC8/IxtJZLywbUiKUNGHbg8/qwwyAzpsBPQGrwvAOdNaYsMxnsEznCQis+JsQxj1zJGpoqJlbbfOtgvgZtnVN8HvNjrh5GLRvemj+cB4Bowel
This looks like a valid Kerberos token, you have already provided dump from a keytab, can you show output of ticket registry after login try? If you're on Windows then you can just use klist program. Also what is your client app that connects to this spring backend?Merari
client app in teams of frontend technology is JSP/JS with Spring and executing klist on client or server ? Also I faced other issue on server where executing kinit to check keytab file trows error. could you also check that in question as UPDATE 1 ?Bowel
Did you solve this?Drub
M
0

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.

Merari answered 3/9, 2019 at 14:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.