Server Setup

1.1 the use ofcas-overlay-templateSetting up the CAS Server

GitHub address: github.com/apereo/cas

Maven is only available up to 5.3. Download 5.3.x

1.2 Configuring an External Tomcat Container

The default address: http://localhost:8443/cas

Default password: casuser/Mellon password: web-INF \classes\application.properties

1.3 Successful Login As shown in the following figure

Client Access

2.1 the Maven rely on

<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>2.3.0. RELEASE</version>
	<relativePath/> <! -- lookup parent from repository -->
</parent>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    <dependency>
    	<groupId>org.projectlombok</groupId>
    	<artifactId>lombok</artifactId>
    	<version>1.18.12</version>
    </dependency>
    <! --CAS client package -->
    <dependency>
    	<groupId>org.jasig.cas.client</groupId>
    	<artifactId>cas-client-core</artifactId>
    	<version>3.5.1 track of</version>
    </dependency>
</dependencies>
Copy the code

2.2 Configuration File

server:
  port: 8091
spring:
  cas:
# listen on exiting interfaces
    sign-out-filters: /
The authentication interface to be intercepted
    auth-filters: / *
    validate-filters: / *
    request-wrapper-filters: / *
    assertion-filters: / *
    redirect-after-validation: true
    use-session: true
# ignore intercept interface, that is, not to intercept, one can use | separating, follow the regular
    ignore-filters: /test
# CAS server address
    server-url-prefix: http://localhost:8443/cas
    server-login-url: ${spring.cas.server-url-prefix}/login
# current project address prefix
    client-url-prefix: http://localhost:8091
Copy the code

2.3 Configuring CAS Parameters

2.3.1 Creating the CAS Configuration Parameter Class SpringCasProperties
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.Arrays;
import java.util.List;

/** * CAS configuration parameters *@author: Fish
 * @date: 2020/05/19 * * /
@ConfigurationProperties(prefix = "spring.cas")
public class SpringCasProperties {

    private static final String separator = ",";
    /** intercepts url */
    private String validateFilters;
    /** Logout interface */
    private String signOutFilters;
    /** Authentication interface to be blocked */
    private String authFilters;
    private String assertionFilters;
    private String requestWrapperFilters;
    / * * need to release the url, one can use | separating, follow the regular * /
    private String ignoreFilters;
    private String serverUrlPrefix;
    private String serverLoginUrl;
    /** Current service address prefix */
    private String clientUrlPrefix;
    private boolean useSession = true;
    private boolean redirectAfterValidation = true;

    public String getIgnoreFilters(a) {
        return ignoreFilters;
    }

    public void setIgnoreFilters(String ignoreFilters) {
        this.ignoreFilters = ignoreFilters;
    }

    public List<String> getValidateFilters(a) {
        return Arrays.asList(validateFilters.split(separator));
    }

    public void setValidateFilters(String validateFilters) {
        this.validateFilters = validateFilters;
    }

    public List<String> getSignOutFilters(a) {
        return Arrays.asList(signOutFilters.split(separator));
    }

    public void setSignOutFilters(String signOutFilters) {
        this.signOutFilters = signOutFilters;
    }

    public List<String> getAuthFilters(a) {
        return Arrays.asList(authFilters.split(separator));
    }

    public void setAuthFilters(String authFilters) {
        this.authFilters = authFilters;
    }

    public List<String> getAssertionFilters(a) {
        return Arrays.asList(assertionFilters.split(separator));
    }

    public void setAssertionFilters(String assertionFilters) {
        this.assertionFilters = assertionFilters;
    }

    public List<String> getRequestWrapperFilters(a) {
        return Arrays.asList(requestWrapperFilters.split(separator));
    }

    public void setRequestWrapperFilters(String requestWrapperFilters) {
        this.requestWrapperFilters = requestWrapperFilters;
    }
    public String getServerUrlPrefix(a) {
        return serverUrlPrefix;
    }

    public void setServerUrlPrefix(String serverUrlPrefix) {
        this.serverUrlPrefix = serverUrlPrefix;
    }

    public String getServerLoginUrl(a) {
        return serverLoginUrl;
    }

    public void setServerLoginUrl(String serverLoginUrl) {
        this.serverLoginUrl = serverLoginUrl;
    }

    public String getClientUrlPrefix(a) {
        return clientUrlPrefix;
    }

    public void setClientUrlPrefix(String clientUrlPrefix) {
        this.clientUrlPrefix = clientUrlPrefix;
    }

    public boolean isRedirectAfterValidation(a) {
        return redirectAfterValidation;
    }

    public void setRedirectAfterValidation(boolean redirectAfterValidation) {
        this.redirectAfterValidation = redirectAfterValidation;
    }

    public boolean isUseSession(a) {
        return useSession;
    }

    public void setUseSession(boolean useSession) {
        this.useSession = useSession; }}Copy the code
2.3.2 Creating the CAS Configuration class SpringCasConfig
import com.fish.casclientdemo1.config.properties.SpringCasProperties;
import lombok.NoArgsConstructor;
import org.jasig.cas.client.authentication.AuthenticationFilter;
import org.jasig.cas.client.session.SingleSignOutFilter;
import org.jasig.cas.client.session.SingleSignOutHttpSessionListener;
import org.jasig.cas.client.util.AssertionThreadLocalFilter;
import org.jasig.cas.client.util.HttpServletRequestWrapperFilter;
import org.jasig.cas.client.validation.Cas30ProxyReceivingTicketValidationFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/** * CAS configuration *@author: Fish
 * @date: 2020/05/19 * * /
@Configuration
@NoArgsConstructor
public class SpringCasConfig {

    @Autowired
    private SpringCasProperties springCasProperties;

    private static boolean casEnabled = true;

    @Bean
    public SpringCasProperties getSpringCasAutoconfig(a) {
        return new SpringCasProperties();
    }

    @Bean
    public ServletListenerRegistrationBean<SingleSignOutHttpSessionListener> singleSignOutHttpSessionListener(a) {
        ServletListenerRegistrationBean<SingleSignOutHttpSessionListener> listener = new ServletListenerRegistrationBean<SingleSignOutHttpSessionListener>();
        listener.setEnabled(casEnabled);
        listener.setListener(new SingleSignOutHttpSessionListener());
        listener.setOrder(1);
        return listener;
    }

    /** * This filter is used to implement the single signout function. The single signout configuration must be placed before other filters **@return* /
    @Bean
    public FilterRegistrationBean singleSignOutFilter(a) {
        FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
        filterRegistration.setFilter(new SingleSignOutFilter());
        filterRegistration.setEnabled(casEnabled);
        if (springCasProperties.getSignOutFilters().size() > 0) {
            filterRegistration.setUrlPatterns(springCasProperties.getSignOutFilters());
        } else {
            filterRegistration.addUrlPatterns("/ *");
        }
        filterRegistration.addInitParameter("casServerUrlPrefix", springCasProperties.getServerUrlPrefix());
        filterRegistration.setOrder(3);
        return filterRegistration;
    }

    /** * This filter is responsible for user authentication **@return* /
    @Bean
    public FilterRegistrationBean authenticationFilter(a) {
        FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
        filterRegistration.setFilter(new AuthenticationFilter());
        filterRegistration.setEnabled(casEnabled);
        if (springCasProperties.getAuthFilters().size() > 0) {
            filterRegistration.setUrlPatterns(springCasProperties.getAuthFilters());
        } else {
            filterRegistration.addUrlPatterns("/ *");
        }
        if(springCasProperties.getIgnoreFilters() ! =null) {
            filterRegistration.addInitParameter("ignorePattern", springCasProperties.getIgnoreFilters());
        }
        filterRegistration.addInitParameter("casServerLoginUrl", springCasProperties.getServerLoginUrl());
        filterRegistration.addInitParameter("serverName", springCasProperties.getClientUrlPrefix());
        filterRegistration.addInitParameter("useSession", springCasProperties.isUseSession() ? "true" : "false");
        filterRegistration.addInitParameter("redirectAfterValidation", springCasProperties.isRedirectAfterValidation() ? "true" : "false");
        filterRegistration.setOrder(4);
        return filterRegistration;
    }

    /** * This filter verifies Ticket and uses CAS 3.0 **@return* /
    @Bean
    public FilterRegistrationBean cas30ProxyReceivingTicketValidationFilter(a) {
        FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
        filterRegistration.setFilter(new Cas30ProxyReceivingTicketValidationFilter());
        filterRegistration.setEnabled(casEnabled);
        if (springCasProperties.getValidateFilters().size() > 0) {
            filterRegistration.setUrlPatterns(springCasProperties.getValidateFilters());
        } else {
            filterRegistration.addUrlPatterns("/ *");
        }
        filterRegistration.addInitParameter("casServerUrlPrefix", springCasProperties.getServerUrlPrefix());
        filterRegistration.addInitParameter("serverName", springCasProperties.getClientUrlPrefix());
        filterRegistration.setOrder(5);
        return filterRegistration;
    }

    @Bean
    public FilterRegistrationBean httpServletRequestWrapperFilter(a) {
        FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
        filterRegistration.setFilter(new HttpServletRequestWrapperFilter());
        filterRegistration.setEnabled(true);
        if (springCasProperties.getRequestWrapperFilters().size() > 0) {
            filterRegistration.setUrlPatterns(springCasProperties.getRequestWrapperFilters());
        } else {
            filterRegistration.addUrlPatterns("/ *");
        }
        filterRegistration.setOrder(6);
        return filterRegistration;
    }

    / * * * the filter made by org.. Jasig cas. Client. Util. AssertionHolder to obtain the user's login name. * such as AssertionHolder. GetAssertion (.) getPrincipal (). The getName (). This class places Assertion information in the ThreadLocal variable so that the application can get the current login information even outside the Web tier@return* /
    @Bean
    public FilterRegistrationBean assertionThreadLocalFilter(a) {
        FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
        filterRegistration.setFilter(new AssertionThreadLocalFilter());
        filterRegistration.setEnabled(true);
        if (springCasProperties.getAssertionFilters().size() > 0) {
            filterRegistration.setUrlPatterns(springCasProperties.getAssertionFilters());
        } else {
            filterRegistration.addUrlPatterns("/ *");
        }
        filterRegistration.setOrder(7);
        returnfilterRegistration; }}Copy the code
2.3.3 Creating a page hello.html

      
<html lang="en" xmlns:th="http://java.sun.com/JSP/Page">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<text>This is the Hello page and the current user is:</text>
<text th:text="${username}"></text>
</body>
</html>
Copy the code

The controller class

import lombok.extern.slf4j.Slf4j;
import org.jasig.cas.client.util.AssertionHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

/ * * *@author: Fish
 * @date: 2020/05/18 * * /
@Controller
@Slf4j
public class CasController {
    @GetMapping("/hello")
    public String hello(Model model) {
        String username = AssertionHolder.getAssertion().getPrincipal().getName();
        model.addAttribute("username", username);
        log.info("Login username :{}", username);
        return "hello"; }}Copy the code

2.4 test

Visit http://localhost:8091/hello to jump to the cas server login page, return after a successful login/hello pages represent success

Pay attention to

Unauthorized services

The CAS service record is empty and no service is defined. Applications that wish to be authenticated by CAS must be clearly defined in the service record.

The solution

  1. findWEB-INF -> classes -> services -> HTTPSandIMAPS-10000001.json

"serviceId" : "^(https|imaps)://.*",
Copy the code

Change to

"serviceId" : "^(https|http|imaps)://.*",
Copy the code
  1. application.propertiesThe new configuration
cas.tgc.secure=false
cas.serviceRegistry.initFromJson=true
Copy the code
  1. Just repack it