ShenheApplication.java 7.65 KB
package com.cnlive.shenhe;

import org.apache.catalina.connector.Connector;
import org.jasig.cas.client.authentication.AuthenticationFilter;
import org.jasig.cas.client.session.SingleSignOutFilter;
import org.jasig.cas.client.util.AssertionThreadLocalFilter;
import org.jasig.cas.client.util.HttpServletRequestWrapperFilter;
import org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Controller;
import tk.mybatis.spring.annotation.MapperScan;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Map;

@SpringBootApplication
@MapperScan(basePackages = {"com.cnlive.shenhe.mapper"})
@EnableAsync
public class ShenheApplication extends SpringBootServletInitializer {
    /**
     * url的前缀
     */
    @Value("${CAS_SERVER_URL_PREFIX}")
    private String CAS_SERVER_URL_PREFIX;
    @Value("${CAS_SERVER_LOGIN_URL}")
    private String CAS_SERVER_LOGIN_URL;
    /**
     * 本机的名称
     */
    @Value("${SERVER_NAME}")
    private String SERVER_NAME;

    /**
     * 登录入口
     */
    @Value("${SERVICE_LOGIN}")
    private String SERVICE_LOGIN;

    /**
     * 登出
     */
    @Value("${SERVICE_LOGINOUT}")
    private String SERVICE_LOGINOUT;


    /**
     * 解决异常信息:
     *  java.lang.IllegalArgumentException:
     *      Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986
     * @return
     */
    @Bean
    public ConfigurableServletWebServerFactory webServerFactory() {
        TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
        factory.addConnectorCustomizers(new TomcatConnectorCustomizer() {
            @Override
            public void customize(Connector connector) {
                connector.setProperty("relaxedQueryChars", "|{}[]/`\\<>");
                connector.setProperty("relaxedPathChars", "|{}[]/`\\<>");
            }
        });
        return factory;
    }

    public static void main(String[] args) {
        SpringApplicationBuilder builder = new SpringApplicationBuilder(ShenheApplication.class);
        builder.headless(true).run(args);
        // 设置Headless模式,linux系统下
        System.setProperty("java.awt.headless", "true");
    }


    /**
     * 用于实现单点登出功能
     *
     * @return
     */
    @Bean
    public FilterRegistrationBean singleSignOutHttpSessionListener() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new SingleSignOutFilter());
        // 设定匹配的路径
        registration.addUrlPatterns("/*");
        Map<String, String> initParameters = new HashMap<String, String>();
        initParameters.put("casServerUrlPrefix", CAS_SERVER_URL_PREFIX);
        registration.setInitParameters(initParameters);
        // 设定加载的顺序
        registration.setOrder(1);
        return registration;
    }

    /**
     * 该过滤器负责用户的认证工作
     *
     * @return
     */
    @Bean
    public FilterRegistrationBean filterAuthenticationRegistration() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new AuthenticationFilter());
        // 设定匹配的路径
        registration.addUrlPatterns("/*");
        Map<String, String> initParameters = new HashMap<String, String>();
        initParameters.put("casServerLoginUrl", CAS_SERVER_LOGIN_URL);
        initParameters.put("service", SERVICE_LOGIN);
        initParameters.put("ignorePattern", "/api/*|/logging/*");
        registration.setInitParameters(initParameters);
        // 设定加载的顺序
        registration.setOrder(2);
        return registration;
    }


    /**
     * 该过滤器负责对Ticket的校验工作
     *
     * @return
     */
    @Bean
    public FilterRegistrationBean filterValidationRegistration() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new Cas20ProxyReceivingTicketValidationFilter());
        // 设定匹配的路径
        registration.addUrlPatterns("/*");
        Map<String, String> initParameters = new HashMap<String, String>();
        initParameters.put("casServerUrlPrefix", CAS_SERVER_URL_PREFIX);
        initParameters.put("serverName", SERVER_NAME);
        initParameters.put("encoding", "utf-8");
        registration.setInitParameters(initParameters);
        // 设定加载的顺序
        registration.setOrder(3);
        return registration;
    }


    /**
     * 该过滤器负责实现HttpServletRequest请求的包裹,
     * 比如允许开发者通过HttpServletRequest的getRemoteUser()方法获得SSO登录用户的登录名,可选配置。
     *
     * @return
     */
    @Bean
    public FilterRegistrationBean filterHttpServletRequestRegistration() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new HttpServletRequestWrapperFilter());
        // 设定匹配的路径
        registration.addUrlPatterns("/*");
        // 设定加载的顺序
        registration.setOrder(4);
        return registration;
    }

    /**
     * 该过滤器使得开发者可以通过org.jasig.cas.client.util.AssertionHolder来获取
     * 用户的登录名。比如AssertionHolder.getAssertion().getPrincipal().getName()。
     *
     * @return
     */
    @Bean
    public FilterRegistrationBean filterAssertionRegistration() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new AssertionThreadLocalFilter());
        // 设定匹配的路径
        registration.addUrlPatterns("/*");
        // 设定加载的顺序
        registration.setOrder(5);
        return registration;
    }

    /**
     * 配置内部类
     */
    @Controller
    @Configuration
    class Config {

        /**
         * 获取日志对象,构造函数传入当前类,查找日志方便定位
         */
        private final Logger logger = LoggerFactory.getLogger(this.getClass());

        @Value("${user.home}")
        private String userName;

        /**
         * 端口
         */
        @Value("${server.port}")
        private String port;

        /**
         * 启动成功
         */
        @Bean
        public ApplicationRunner applicationRunner() {
            return applicationArguments -> {
                try {
                    InetAddress ia = InetAddress.getLocalHost();
                    //获取本机内网IP
                    logger.info("启动成功:" + "http://" + ia.getHostAddress() + ":" + port + "/");
                    logger.info("${user.home} :" + userName);
                } catch (UnknownHostException ex) {
                    ex.printStackTrace();
                }
            };
        }

    }
}