CAS过滤器在部署war时不拦截服务票证

问题描述 投票:0回答:1

我有一个Spring Boot应用程序,可以对CAS服务器进行身份验证。当我执行“mvn spring-boot:run”时,登录正确完成:

  1. 致电URL_1_APP
  2. 重定向到cas / login
  3. 填写凭据并提交
  4. 重定向到Service_id_path?ticket = ST-XX -...
  5. 重定向到请求的URL URL_1_APP

但是当我执行“mvn package”并在tomcat服务器中部署war时,最后的重定向没有完成:

  1. 致电URL_1_APP
  2. 重定向到cas / login
  3. 填写凭据并提交
  4. 重定向到Service_id_path?ticket = ST-XX -... - >重定向到URL_1_APP永远不会

我正在使用:Spring Boot 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;
    }

}

先感谢您。

java spring-boot tomcat war cas
1个回答
0
投票

生成错误的原因是,当在服务器上部署战争时,包含上下文路径以访问应用程序:资源http://localhost:9000/hello更改为http://localhost:9000/application-version/hello

因此,在服务属性方法中需要进行修改:

@Bean
public ServiceProperties serviceProperties() {
    ServiceProperties serviceProperties = new ServiceProperties();
    serviceProperties.setService("http://localhost:"+serverPort+"/application-version/kaka");
    serviceProperties.setSendRenew(false);
    serviceProperties.setAuthenticateAllArtifacts(true);
    return serviceProperties;
}

但是没有必要在cas过滤器方法中包含此上下文路径:

@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;
}
© www.soinside.com 2019 - 2024. All rights reserved.