Backend Development 10 min read

Integrating CAS Single Sign-On with Spring Boot for Front‑Back End Separation

This article explains how to deploy a CAS server, configure the cas-client dependency, set up Spring Boot annotations and cookie handling, share sessions across multiple services, and resolve cross‑origin and authentication redirects for a Vue front‑end separated from legacy JSP back‑ends.

Selected Java Interview Questions
Selected Java Interview Questions
Selected Java Interview Questions
Integrating CAS Single Sign-On with Spring Boot for Front‑Back End Separation

Background

The project originally consisted of several JSP/Thymeleaf back‑ends that shared a CAS single sign‑on implementation, and the goal is to split the front‑end into a Vue application while keeping the old systems functional.

Project background: multiple back‑ends using JSP or thymeleaf with CAS for single sign‑on.

After business expansion, the systems need to be separated into independent services, with the Vue front‑end accessing the back‑ends without additional login steps and handling cross‑origin requests.

The article demonstrates how to deploy cas-server , integrate cas-client using the net.unicon.cas dependency, and share sessions between different cas-client instances.

Typical CAS Integration

Add the following Maven dependency:

<dependency>
  <groupId>net.unicon.cas</groupId>
  <artifactId>cas-client-autoconfig-support</artifactId>
  <version>2.3.0-GA</version>
</dependency>

Configure the CAS server URL and validation type:

cas.server-url-prefix=https://****/cas
cas.server-login-url=https://****/cas/login
cas.client-host-url=http://****:8080
cas.validation-type=CAS

Enable the client in a Spring Boot application:

import net.unicon.cas.client.configuration.EnableCasClient;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@EnableCasClient
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Whitelist Configuration – Method 1

Extend CasClientConfigurerAdapter and override configureAuthenticationFilter :

import net.unicon.cas.client.configuration.EnableCasClient;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Configuration;
import java.util.Map;

@Configuration
public class CasClientConfig extends CasClientConfigurerAdapter {
    @Override
    public void configureAuthenticationFilter(FilterRegistrationBean authenticationFilter) {
        super.configureAuthenticationFilter(authenticationFilter);
        Map
initParameters = authenticationFilter.getInitParameters();
        // example: ignorePattern
        initParameters.put("ignorePattern", "/ignoreUrl1/");
    }
}

// Cookie serializer for Spring Session
@Bean
public CookieSerializer httpSessionIdResolver() {
    DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
    cookieSerializer.setCookieName("JSESSIONID");
    cookieSerializer.setUseHttpOnlyCookie(false);
    cookieSerializer.setSameSite(null);
    return cookieSerializer;
}

Whitelist Configuration – Method 2

Configure URLs that need filtering directly in application.properties :

cas.authentication-url-patterns=/need-filter-url/*,

Front‑Back End Separation Project

Configure the CAS client and CORS handling for the Vue project:

import net.unicon.cas.client.configuration.CasClientConfigurerAdapter;
import net.unicon.cas.client.configuration.EnableCasClient;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import java.util.Map;

@Configuration
public class CasClientConfig extends CasClientConfigurerAdapter {
    @Override
    public void configureAuthenticationFilter(FilterRegistrationBean authenticationFilter) {
        super.configureAuthenticationFilter(authenticationFilter);
        Map
initParameters = authenticationFilter.getInitParameters();
        initParameters.put("authenticationRedirectStrategyClass", "com.demo.filter.CustomAuthRedirectStrategy");
        initParameters.put("ignorePattern", "/ignoreUrl1/|/ignoreUrl2/|/ignoreUrl3/");
    }

    @Bean
    public FilterRegistrationBean corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("http://****:8081");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        source.registerCorsConfiguration("/**", config);
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        registrationBean.setFilter(new CorsFilter(source));
        registrationBean.addUrlPatterns("/url1/*", "/url2/*", "/url3/*");
        registrationBean.setOrder(-2147483648);
        return registrationBean;
    }
}

Custom authentication redirect strategy:

import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.jasig.cas.client.authentication.AuthenticationRedirectStrategy;

public class CustomAuthRedirectStrategy implements AuthenticationRedirectStrategy {
    @Override
    public void redirect(HttpServletRequest request, HttpServletResponse response, String serviceUrl) throws IOException {
        response.setCharacterEncoding("utf-8");
        response.setContentType("application/json; charset=utf-8");
        response.setStatus(HttpStatus.UNAUTHORIZED.value());
    }
}

Front‑End Code

http.js – Axios wrapper with error handling and credential support:

import axios from 'axios';
import helper from './helper';
var qs = require('qs');
const ERR_CODE_LIST = {
  [400]: "请求错误",
  [401]: "登录失效或在其他地方已登录",
  [403]: "拒绝访问",
  [404]: "请求地址出错",
  [408]: "请求超时",
  [500]: "服务器内部错误",
  [501]: "服务未实现",
  [502]: "网关错误",
  [503]: "服务不可用",
  [504]: "网关超时",
  [505]: "HTTP版本不受支持"
};
export function getErrMsg(error) {
  if (!error.response) {
    return { errCode: null, errMsg: "网络不可用,请刷新重试" };
  }
  const errCode = error.response.status;
  const errMsg = ERR_CODE_LIST[errCode];
  return { errCode, errMsg: errMsg ? `${errMsg} [${errCode}]` : error.message };
}
function apiAxios(method, rootUrl, url, params) {
  return axios({
    method,
    url,
    data: qs.stringify(params),
    baseURL: rootUrl,
    timeout: 600000,
    dataType: "json",
    async: true,
    crossDomain: true,
    withCredentials: true
  }).catch(error => {
    const { errCode, errMsg } = getErrMsg(error);
    if (errCode == 401) {
      let hurl = 'http://****:8080/front/redirect';
      window.location.href = 'http://****/cas/login?service=' + hurl;
    } else {
      showMsg(errMsg);
    }
    return Promise.reject(error);
  });
}
export default {
  get: (rootUrl, url, params) => apiAxios('GET', rootUrl, url, params),
  post: (rootUrl, url, params) => apiAxios('post', rootUrl, url, params)
};

Api.js – Simple API wrapper:

import http from "./http";
let root = 'http://****:8080';
export default {
  getUserInfo(data) {
    return http.get(root, '/user/userInfo', data);
  }
};

user.vue – Example of calling the API:

async getUserInfo() {
  let obj = { param1: value1 };
  let userInfo = await this.$api.getUserInfo(obj);
  console.log(userInfo, '11');
},

Redirect Controller – Sends the browser to the front‑end after successful CAS authentication:

@RequestMapping(value = "redirect", method = RequestMethod.GET)
public void redirect(HttpServletRequest request, HttpServletResponse httpServletResponse) throws IOException {
    // Redirect to front‑end page
    httpServletResponse.sendRedirect("http://****:8081/#/demo.html");
}

The complete solution enables users who have logged into the legacy JSP system to access the new Vue front‑end without additional login steps, while sharing CAS sessions across multiple back‑end services.

JavaSpring BootAuthenticationCASSingle Sign-OnFront‑Back End Separation
Selected Java Interview Questions
Written by

Selected Java Interview Questions

A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.