У меня есть приложение Spring Boot, которое проходит проверку подлинности на сервере CAS.
Когда я выполняю «mvn spring-boot:run
», вход выполняется правильно:
Позвоните на URL_1_APP
Перенаправление на cas / login
Заполните учетные данные и отправьте
Перенаправление на Service_id_path? Ticket = ST-XX -...
Перенаправление на запрошенный URL URL_1_APP
Но когда я выполняю "mvn package
" и развертываю войну на сервере tomcat, последнее перенаправление не выполняется:
- Позвонить на URL_1_APP
- Перенаправление на cas / login
- Заполните учетные данные и отправьте
- Перенаправление на Service_id_path? Ticket = ST-XX -... -> Перенаправление на URL_1_APP никогда не выполняется
Я использую:
Пружинный ботинок 1.5.2.
Tomcat 9.0.16
JDK 11
Это мой начальный класс:
package com.qim.ptp;
import com.qim.ptp.config.YmlPropertyFactory;
import org.jasig.cas.client.session.SingleSignOutFilter;
import org.jasig.cas.client.session.SingleSignOutHttpSessionListener;
import org.jasig.cas.client.validation.Cas30ServiceTicketValidator;
import org.jasig.cas.client.validation.TicketValidator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.event.EventListener;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.security.cas.ServiceProperties;
import org.springframework.security.cas.authentication.CasAuthenticationProvider;
import org.springframework.security.cas.web.CasAuthenticationEntryPoint;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.logout.LogoutFilter;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import javax.servlet.http.HttpSessionEvent;
@ComponentScan(basePackages = {"com.qim"})
@ServletComponentScan
@SpringBootApplication
@EnableJpaRepositories(basePackages = {"com.qim.ptp.repository"})
@PropertySource(factory = YmlPropertyFactory.class, value = "file:${config.path}")
public class BackApplication extends SpringBootServletInitializer {
private static final Logger log = LoggerFactory.getLogger(BackApplication.class);
@Value("${qim.cas.service-id}")
private String serviceId;
@Value("${qim.cas.path.base}")
private String casBasePath;
@Value("${qim.cas.path.login}")
private String casLoginPath;
@Value("${qim.cas.path.logout}")
private String casLogoutPath;
@Value("${qim.cas.admin.username}")
private String casUsername;
@Value("${qim.cas.admin.password}")
private String casPassword;
@Value("${qim.cas.admin.role}")
private String casRole;
@Value("${qim.cas.admin.key}")
private String casKey;
@Value("${qim.paths.base.version.v1}")
private String basePath;
@Value("${qim.paths.logout}")
private String logoutPath;
@Value("${server.port}")
private String serverPort;
public static void main( String[] args ) {
log.info("Init application");
SpringApplication.run(BackApplication.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(BackApplication.class);
}
@Bean
public ServiceProperties serviceProperties() {
ServiceProperties serviceProperties = new ServiceProperties();
serviceProperties.setService("http://localhost:"+serverPort+"/kaka");
serviceProperties.setSendRenew(false);
serviceProperties.setAuthenticateAllArtifacts(true);
return serviceProperties;
}
@Bean
@Primary
public AuthenticationEntryPoint authenticationEntryPoint(
ServiceProperties sP) {
CasAuthenticationEntryPoint entryPoint = new CasAuthenticationEntryPoint();
entryPoint.setLoginUrl(casBasePath+casLoginPath);
entryPoint.setServiceProperties(sP);
return entryPoint;
}
@Bean
public TicketValidator ticketValidator() {
return new Cas30ServiceTicketValidator(casBasePath);
}
@Bean
public CasAuthenticationProvider casAuthenticationProvider() {
CasAuthenticationProvider provider = new CasAuthenticationProvider();
provider.setServiceProperties(serviceProperties());
provider.setTicketValidator(ticketValidator());
provider.setUserDetailsService(
s -> new User(casUsername, casPassword, true, true, true, true,
AuthorityUtils.createAuthorityList(casRole)
)
);
provider.setKey(casKey);
return provider;
}
@Bean
public SecurityContextLogoutHandler securityContextLogoutHandler() {
return new SecurityContextLogoutHandler();
}
@Bean
public LogoutFilter logoutFilter() {
LogoutFilter logoutFilter = new LogoutFilter(
casBasePath+casLogoutPath,
securityContextLogoutHandler());
logoutFilter.setFilterProcessesUrl(basePath+logoutPath);
return logoutFilter;
}
@Bean
public SingleSignOutFilter singleSignOutFilter() {
SingleSignOutFilter singleSignOutFilter = new SingleSignOutFilter();
singleSignOutFilter.setCasServerUrlPrefix(casBasePath);
singleSignOutFilter.setIgnoreInitConfiguration(true);
return singleSignOutFilter;
}
@EventListener
public SingleSignOutHttpSessionListener singleSignOutHttpSessionListener(
HttpSessionEvent event) {
return new SingleSignOutHttpSessionListener();
}
}
В этом классе я настраиваю фильтры Spring Security:
package com.qim.ptp.config;
import org.jasig.cas.client.session.SingleSignOutFilter;
import org.jasig.cas.client.session.SingleSignOutHttpSessionListener;
import org.jasig.cas.client.validation.Cas30ServiceTicketValidator;
import org.jasig.cas.client.validation.TicketValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.event.EventListener;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.cas.ServiceProperties;
import org.springframework.security.cas.authentication.CasAuthenticationProvider;
import org.springframework.security.cas.web.CasAuthenticationEntryPoint;
import org.springframework.security.cas.web.CasAuthenticationFilter;
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.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.logout.LogoutFilter;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.security.web.firewall.HttpFirewall;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import javax.servlet.http.HttpSessionEvent;
import java.util.Arrays;
@EnableWebSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private AuthenticationProvider authenticationProvider;
private AuthenticationEntryPoint authenticationEntryPoint;
private SingleSignOutFilter singleSignOutFilter;
private LogoutFilter logoutFilter;
private CasAuthenticationFilter filter;
@Value("${qim.paths.base.version.v1}")
private String basePath;
@Value("${qim.paths.logout}")
private String logoutPath;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.addFilter(this.filter)
.authorizeRequests()
.regexMatchers("/.*")
.authenticated()
.and()
.authorizeRequests()
.regexMatchers("/")
.permitAll()
.and()
.httpBasic()
.authenticationEntryPoint(authenticationEntryPoint)
.and()
.logout().logoutSuccessUrl(basePath+logoutPath)
.and()
.addFilterBefore(singleSignOutFilter, CasAuthenticationFilter.class)
.addFilterBefore(logoutFilter, LogoutFilter.class);
}
@Autowired
public SecurityConfig(CasAuthenticationProvider casAuthenticationProvider, AuthenticationEntryPoint eP,
LogoutFilter lF
, SingleSignOutFilter ssF
) {
this.authenticationProvider = casAuthenticationProvider;
this.authenticationEntryPoint = eP;
this.logoutFilter = lF;
this.singleSignOutFilter = ssF;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider);
}
@Override
protected AuthenticationManager authenticationManager() throws Exception {
return new ProviderManager(Arrays.asList(authenticationProvider));
}
@Bean
public CasAuthenticationFilter casAuthenticationFilter(ServiceProperties sP) throws Exception {
CasAuthenticationFilter filter = new CasAuthenticationFilter();
filter.setServiceProperties(sP);
filter.setFilterProcessesUrl("/kaka");
filter.setAuthenticationManager(authenticationManager());
this.filter = filter;
return filter;
}
}
Заранее спасибо.