/******************************************************************************* * Copyright 2017 Cognizant Technology Solutions * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. ******************************************************************************/ package com.cognizant.devops.platformservice.security.config.kerberos; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.ListIterator; import javax.servlet.Filter; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; import org.springframework.core.io.Resource; 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.builders.WebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.kerberos.authentication.KerberosAuthenticationProvider; import org.springframework.security.kerberos.authentication.KerberosServiceAuthenticationProvider; import org.springframework.security.kerberos.authentication.sun.SunJaasKerberosClient; import org.springframework.security.kerberos.authentication.sun.SunJaasKerberosTicketValidator; import org.springframework.security.kerberos.web.authentication.SpnegoAuthenticationProcessingFilter; import org.springframework.security.kerberos.web.authentication.SpnegoEntryPoint; import org.springframework.security.ldap.DefaultSpringSecurityContextSource; import org.springframework.security.web.DefaultSecurityFilterChain; import org.springframework.security.web.FilterChainProxy; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; import org.springframework.security.web.csrf.CsrfFilter; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import com.cognizant.devops.platformcommons.config.ApplicationConfigProvider; import com.cognizant.devops.platformcommons.config.SingleSignOnConfig; import com.cognizant.devops.platformservice.security.config.AuthenticationUtils; import com.cognizant.devops.platformservice.security.config.InsightsAuthenticationFilter; import com.cognizant.devops.platformservice.security.config.InsightsCrossScriptingFilter; import com.cognizant.devops.platformservice.security.config.InsightsCustomCsrfFilter; import com.cognizant.devops.platformservice.security.config.InsightsResponseHeaderWriterFilter; import com.cognizant.devops.platformservice.security.config.saml.ResourceLoaderService; @ComponentScan(basePackages = { "com.cognizant.devops" }) @Configuration @EnableWebSecurity @Order(value = 3) @Conditional(InsightsKerberosBeanInitializationCondition.class) public class InsightsSecurityConfigurationAdapterKerberos extends WebSecurityConfigurerAdapter { private static Logger LOG = LogManager.getLogger(InsightsSecurityConfigurationAdapterKerberos.class); private SingleSignOnConfig singleSignOnConfig = ApplicationConfigProvider.getInstance().getSingleSignOnConfig(); DefaultSpringSecurityContextSource contextSource; @Autowired ResourceLoaderService resourceLoaderService; final String AUTH_TYPE = "Kerberos"; @Autowired private AuthenticationUtils authenticationUtils; @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { LOG.debug("message Inside InsightsSecurityConfigurationAdapterKerberos, AuthenticationManagerBuilder **** {} ", ApplicationConfigProvider.getInstance().getAutheticationProtocol()); if (AUTH_TYPE.equalsIgnoreCase(ApplicationConfigProvider.getInstance().getAutheticationProtocol())) { auth.authenticationProvider(kerberosAuthenticationProvider()) .authenticationProvider(kerberosServiceAuthenticationProvider()); } } @Override protected void configure(HttpSecurity http) throws Exception { LOG.debug("message Inside InsightsSecurityConfigurationAdapterKerberos,HttpSecurity **** {} ", ApplicationConfigProvider.getInstance().getAutheticationProtocol()); if (AUTH_TYPE.equalsIgnoreCase(ApplicationConfigProvider.getInstance().getAutheticationProtocol())) { LOG.debug("message Inside SAMLAuthConfig, check http security **** "); http.cors(); http.csrf().ignoringAntMatchers(AuthenticationUtils.CSRF_IGNORE) .csrfTokenRepository(authenticationUtils.csrfTokenRepository()) .and().addFilterAfter(new InsightsCustomCsrfFilter(), CsrfFilter.class); http.exceptionHandling().authenticationEntryPoint(spnegoEntryPoint()); http.addFilterAfter(kerberosFilter(), BasicAuthenticationFilter.class); http.anonymous().disable().authorizeRequests().antMatchers("/error").permitAll().antMatchers("/admin/**") .access("hasAuthority('Admin')").antMatchers("/saml/**").permitAll() //.antMatchers("/user/insightsso/**").permitAll() ///logout .anyRequest().authenticated(); http.logout().logoutSuccessUrl("/"); } } /** * Used to add filter chain based on Request Matcher * * @return * @throws Exception */ @Bean @Conditional(InsightsKerberosBeanInitializationCondition.class) public FilterChainProxy kerberosFilter() throws Exception { LOG.debug("message Inside InsightsSecurityConfigurationAdapterKerberos FilterChainProxy, initial bean **** "); /*AuthenticationUtils.setSecurityFilterchain( new DefaultSecurityFilterChain(new AntPathRequestMatcher("/kerberos/login/**"), spnegoEntryPoint()));*/ /*AuthenticationUtils.setSecurityFilterchain(new DefaultSecurityFilterChain( new AntPathRequestMatcher("/user/insightsso/**"), insightsSSOProcessingFilter()));*/ List<Filter> filters = new ArrayList<>(); filters.add(0, new InsightsCustomCsrfFilter()); filters.add(1, new InsightsCrossScriptingFilter()); filters.add(2, insightsServiceProcessingFilter()); filters.add(3, new InsightsResponseHeaderWriterFilter()); AuthenticationUtils .setSecurityFilterchain(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/**"), filters)); ListIterator<SecurityFilterChain> securityFilters = AuthenticationUtils.getSecurityFilterchains() .listIterator(); while (securityFilters.hasNext()) { SecurityFilterChain as = securityFilters.next(); LOG.debug("message Inside FilterChainProxy, initial bean name {} **** ", Arrays.toString(as.getFilters().toArray())); } return new FilterChainProxy(AuthenticationUtils.getSecurityFilterchains());//chains } /** * used to configure WebSecurity ignore */ @Override public void configure(WebSecurity web) throws Exception { web.ignoring().antMatchers("/settings/getLogoImage"); web.ignoring().antMatchers("/datasource/**"); } /** * Used to configure authenticationManagerBean */ @Override @Bean public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } /*@Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.authenticationProvider(kerberosAuthenticationProvider()) .authenticationProvider(kerberosServiceAuthenticationProvider()); }*/ /** * Used to configure kerberos Authentication Provider * * @return */ @Bean @Conditional(InsightsKerberosBeanInitializationCondition.class) public KerberosAuthenticationProvider kerberosAuthenticationProvider() { KerberosAuthenticationProvider provider = new KerberosAuthenticationProvider(); SunJaasKerberosClient client = new SunJaasKerberosClient(); client.setDebug(true); provider.setKerberosClient(client); provider.setUserDetailsService(kerberosUserDetailsService()); return provider; } /** * Used to configure authentication Filter for all Request Matcher * * @return * @throws Exception */ @Bean @Conditional(InsightsKerberosBeanInitializationCondition.class) public InsightsAuthenticationFilter insightsServiceProcessingFilter() throws Exception { InsightsAuthenticationFilter filter = new InsightsAuthenticationFilter("/**", authenticationManager()); return filter; } /** * Entry point for kerberos validation * * @return */ @Bean @Conditional(InsightsKerberosBeanInitializationCondition.class) public SpnegoEntryPoint spnegoEntryPoint() { SpnegoEntryPoint spnegoEntryPoint = new SpnegoEntryPoint();//"/user/insightsso/authenticateSSO" return spnegoEntryPoint; } /** * used to set default authentication filter * @param authenticationManager * @return */ @Bean @Conditional(InsightsKerberosBeanInitializationCondition.class) public SpnegoAuthenticationProcessingFilter spnegoAuthenticationProcessingFilter( AuthenticationManager authenticationManager) { SpnegoAuthenticationProcessingFilter filter = new SpnegoAuthenticationProcessingFilter(); filter.setAuthenticationManager(authenticationManager); return filter; } /** * used to set kerberos Service Authentication Provider * * @return */ @Bean @Conditional(InsightsKerberosBeanInitializationCondition.class) public KerberosServiceAuthenticationProvider kerberosServiceAuthenticationProvider() { KerberosServiceAuthenticationProvider provider = new KerberosServiceAuthenticationProvider(); provider.setTicketValidator(sunJaasKerberosTicketValidator()); provider.setUserDetailsService(kerberosUserDetailsService()); return provider; } /** * Default Kerberos ticket validator * * @return */ @Bean @Conditional(InsightsKerberosBeanInitializationCondition.class) public SunJaasKerberosTicketValidator sunJaasKerberosTicketValidator() { Resource storeFile = resourceLoaderService .getResource("file:" + singleSignOnConfig.getKeyTabLocationKerberos()); SunJaasKerberosTicketValidator ticketValidator = new SunJaasKerberosTicketValidator(); ticketValidator.setServicePrincipal(singleSignOnConfig.getServicePrincipalKerberos()); ticketValidator.setKeyTabLocation(storeFile); ticketValidator.setDebug(true); return ticketValidator; } /** * user detail service for kerberos * * @return */ @Bean @Conditional(InsightsKerberosBeanInitializationCondition.class) public KerberosUserDetailsService kerberosUserDetailsService() { return new KerberosUserDetailsService(); } }