package demo.app; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.FileSystemResource; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity; import org.springframework.security.kerberos.authentication.KerberosServiceAuthenticationProvider; import org.springframework.security.kerberos.authentication.sun.SunJaasKerberosTicketValidator; import org.springframework.security.kerberos.client.config.SunJaasKrb5LoginConfig; import org.springframework.security.kerberos.client.ldap.KerberosLdapContextSource; import org.springframework.security.kerberos.web.authentication.SpnegoAuthenticationProcessingFilter; import org.springframework.security.kerberos.web.authentication.SpnegoEntryPoint; import org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider; import org.springframework.security.ldap.search.FilterBasedLdapUserSearch; import org.springframework.security.ldap.userdetails.LdapUserDetailsMapper; import org.springframework.security.ldap.userdetails.LdapUserDetailsService; import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; @Configuration @EnableWebMvcSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Value("${app.ad-domain}") private String adDomain; @Value("${app.ad-server}") private String adServer; @Value("${app.service-principal}") private String servicePrincipal; @Value("${app.keytab-location}") private String keytabLocation; @Value("${app.ldap-search-base}") private String ldapSearchBase; @Value("${app.ldap-search-filter}") private String ldapSearchFilter; @Override protected void configure(HttpSecurity http) throws Exception { http .exceptionHandling() .authenticationEntryPoint(spnegoEntryPoint()) .and() .authorizeRequests() .antMatchers("/", "/home").permitAll() .anyRequest().authenticated() .and() .formLogin() .loginPage("/login").permitAll() .and() .logout() .permitAll() .and() .addFilterBefore( spnegoAuthenticationProcessingFilter(authenticationManagerBean()), BasicAuthenticationFilter.class); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth .authenticationProvider(activeDirectoryLdapAuthenticationProvider()) .authenticationProvider(kerberosServiceAuthenticationProvider()); } @Bean public ActiveDirectoryLdapAuthenticationProvider activeDirectoryLdapAuthenticationProvider() { return new ActiveDirectoryLdapAuthenticationProvider(adDomain, adServer); } @Bean public SpnegoEntryPoint spnegoEntryPoint() { return new SpnegoEntryPoint("/login"); } @Bean public SpnegoAuthenticationProcessingFilter spnegoAuthenticationProcessingFilter( AuthenticationManager authenticationManager) { SpnegoAuthenticationProcessingFilter filter = new SpnegoAuthenticationProcessingFilter(); filter.setAuthenticationManager(authenticationManager); return filter; } @Bean public KerberosServiceAuthenticationProvider kerberosServiceAuthenticationProvider() { KerberosServiceAuthenticationProvider provider = new KerberosServiceAuthenticationProvider(); provider.setTicketValidator(sunJaasKerberosTicketValidator()); provider.setUserDetailsService(ldapUserDetailsService()); return provider; } @Bean public SunJaasKerberosTicketValidator sunJaasKerberosTicketValidator() { SunJaasKerberosTicketValidator ticketValidator = new SunJaasKerberosTicketValidator(); ticketValidator.setServicePrincipal(servicePrincipal); ticketValidator.setKeyTabLocation(new FileSystemResource(keytabLocation)); ticketValidator.setDebug(true); return ticketValidator; } @Bean public KerberosLdapContextSource kerberosLdapContextSource() { KerberosLdapContextSource contextSource = new KerberosLdapContextSource(adServer); contextSource.setLoginConfig(loginConfig()); return contextSource; } @Bean public SunJaasKrb5LoginConfig loginConfig() { SunJaasKrb5LoginConfig loginConfig = new SunJaasKrb5LoginConfig(); loginConfig.setKeyTabLocation(new FileSystemResource(keytabLocation)); loginConfig.setServicePrincipal(servicePrincipal); loginConfig.setDebug(true); loginConfig.setIsInitiator(true); return loginConfig; } @Bean public LdapUserDetailsService ldapUserDetailsService() { FilterBasedLdapUserSearch userSearch = new FilterBasedLdapUserSearch(ldapSearchBase, ldapSearchFilter, kerberosLdapContextSource()); LdapUserDetailsService service = new LdapUserDetailsService(userSearch); service.setUserDetailsMapper(new LdapUserDetailsMapper()); return service; } }