CAS Server and Client Integration with Spring Boot: Configuration, Custom Authentication Filter, and CORS Handling
This article provides a step‑by‑step guide for building a CAS server and client with Spring Boot, covering WAR deployment, configuration file adjustments, custom authentication redirect strategies, CORS setup, and troubleshooting ticket validation and cross‑origin issues.
Introduction: The article demonstrates how to build and configure a CAS (Central Authentication Service) server and client using Spring Boot and Tomcat.
1. CAS Server Setup
1.1 Deploy WAR
Build the CAS 5.3 overlay template (https://github.com/apereo/cas-overlay-template) and deploy the generated WAR to Tomcat.
1.2 Modify Configuration Files
Enable HTTP protocol by editing
apache-tomcat-8.5.53\webapps\cas\WEB-INF\classes\services\HTTPSandIMAPS-10000001.jsonand adding http to the serviceId regex.
{
"@class" : "org.apereo.cas.services.RegexRegisteredService",
"serviceId" : "^(https|http|imaps)://.*",
"name" : "HTTPS and IMAPS",
"id" : 10000001,
"description" : "This service definition authorizes all application urls that support HTTPS and IMAPS protocols.",
"evaluationOrder" : 10000
}Add the following properties to
apache-tomcat-8.5.53\webapps\cas\WEB-INF\classes\application.properties:
cas.tgc.secure=false
cas.serviceRegistry.initFromJson=trueConfigure default login user and logout redirect:
cas.authn.accept.users=admin::admin
# allow logout redirect
cas.logout.followServiceRedirects=true1.3 Start Server
Start Tomcat to run the CAS server.
2. Client Construction
2.1 Maven Dependency
<dependency>
<groupId>net.unicon.cas</groupId>
<artifactId>cas-client-autoconfig-support</artifactId>
<version>2.3.0-GA</version>
</dependency>2.2 YAML Configuration
cas:
server-url-prefix: http://172.19.25.113:8080/cas
server-login-url: http://172.19.25.113:8080/cas/login
client-host-url: http://172.19.25.113:1010
validation-type: cas
use-session: true
authentication-url-patterns:
/auth2.3 Backend Code
Add @EnableCasClient to the Spring Boot main class.
@EnableCasClient
@SpringBootApplication
public class SpringbootCasDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootCasDemoApplication.class, args);
}
}Implement a custom AuthenticationRedirectStrategy that returns JSON "401" instead of redirecting.
public class CustomAuthRedirectStrategy implements AuthenticationRedirectStrategy {
@Override
public void redirect(HttpServletRequest request, HttpServletResponse response, String url) throws IOException {
response.setCharacterEncoding("utf-8");
response.setContentType("application/json; charset=utf-8");
PrintWriter out = response.getWriter();
out.write("401");
}
}Configure the custom strategy and CORS filter in a @Configuration class.
@Configuration
public class CasAuthConfig extends CasClientConfigurerAdapter {
@Override
public void configureAuthenticationFilter(FilterRegistrationBean authenticationFilter) {
Map<String, String> initParameters = authenticationFilter.getInitParameters();
initParameters.put("authenticationRedirectStrategyClass",
"cc.jasonwang.springbootcasdemo.config.CustomAuthRedirectStrategy");
}
@Override
public void configureValidationFilter(FilterRegistrationBean validationFilter) {
Map<String, String> initParameters = validationFilter.getInitParameters();
initParameters.put("encodeServiceUrl", "false");
}
@Bean
public FilterRegistrationBean<CorsFilter> corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>();
bean.setFilter(new CorsFilter(source));
bean.setOrder(-2147483648);
return bean;
}
}Controller example for authentication and logout handling.
@RestController
public class HelloController {
@Value("${cas.server-url-prefix}")
private String casServerUrlPrefix;
@GetMapping("/auth")
public void auth(HttpServletRequest request, HttpServletResponse response, HttpSession session) {
// implementation omitted for brevity
}
@GetMapping("/logout")
public RedirectView logout(HttpServletRequest request, HttpServletResponse response, HttpSession session) {
session.invalidate();
String indexPageUrl = "http://127.0.0.1";
return new RedirectView(casServerUrlPrefix + "/logout?service=" + indexPageUrl);
}
}2.4 Front‑end Page
Simple HTML page that sends an AJAX request to /auth and redirects to the CAS login page when a 401 response is received.
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<span>Single sign‑on address:</span><input class="url" type="text"/><br/>
<button type="button" class="button">Login</button><br/>
<div class="response" style="width:200px;height:200px;border:1px solid #333;"></div>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script type="text/javascript">
$(".button").click(function(){
$.get("http://172.19.25.113:1010/auth", function(data){
$(".response").text(data);
if(data == 401){
window.location.href = "http://localhost:8080/cas/login?service=http://172.19.25.113:1010/auth?redirectUrl=http://127.0.0.1";
}
})
})
</script>
</body>
</html>3. Issue Records
3.1 AuthenticationFilter Redirection Causing CORS
In a front‑back separation scenario the default AuthenticationFilter redirects unauthenticated requests to the CAS login page, which triggers cross‑origin errors. The custom redirect strategy returns a 401 status so the front‑end can handle the redirect itself.
3.2 CORS Configuration Differences
Two approaches are compared: overriding WebMvcConfigurationSupport.addCorsMappings (effective at the interceptor level) and registering a CorsFilter bean (effective at the filter level). The latter is used in the final configuration.
3.3 Ticket Validation Service URL Encoding Issue
When the CAS server validates a ticket, the service URL is URL‑encoded on the client side but not on the server side, causing mismatched URLs and validation failure. Setting the encodeServiceUrl parameter to false in Cas20ProxyReceivingTicketValidationFilter resolves the problem.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Code Ape Tech Column
Former Ant Group P8 engineer, pure technologist, sharing full‑stack Java, job interview and career advice through a column. Site: java-family.cn
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
