Understanding Session Management, SSO, and CAS Implementation in Java

This article explains the challenges of traditional session mechanisms in distributed systems, explores session sharing solutions such as replication and centralized storage, details the design and flow of Single Sign‑On (SSO) using CAS, compares CAS with OAuth2, and provides complete Java code examples for a demo implementation.

Top Architect
Top Architect
Top Architect
Understanding Session Management, SSO, and CAS Implementation in Java

Background

When a company has many products, users must log in to each system separately, leading to poor user experience and increased password management costs. A unified authentication mechanism is needed to allow a single account to access multiple systems.

Traditional Session Mechanism

HTTP is stateless, so servers create a new session for each request and store a JSESSIONID cookie on the client. The server looks up the session by this ID on subsequent requests. However, in a clustered environment, a user may be routed to a different server that does not have the original session, causing login failures.

Session Sharing Solutions

Session replication – copy session data to all servers (high cost, latency).

Centralized session storage – store sessions in a shared store like Redis.

Single Sign‑On (SSO) Overview

SSO solves the multi‑login problem by using a central authentication domain (e.g., oauth.com) that issues a ticket. The ticket is exchanged for a session ID stored in a shared store, allowing other services to retrieve the user’s session without re‑authentication.

CAS (Central Authentication Service) Flow

User accesses b.com, is redirected to ouath.com for login.

After successful login, ouath.com creates a ticket and stores ticket → sessionId in Redis. b.com receives the ticket, looks up the session ID in Redis, loads the user into its own session, and deletes the ticket.

Code Example (Java Spring Boot)

User entity:

public class UserForm implements Serializable {
    private static final long serialVersionUID = 1L;
    private String username;
    private String password;
    private String backurl;
    // getters and setters omitted for brevity
}

Login controller (simplified):

@Controller
public class IndexController {
    @Autowired
    private RedisTemplate redisTemplate;

    @GetMapping("/toLogin")
    public String toLogin(Model model, HttpServletRequest request) {
        // omitted logic for brevity
        return "login";
    }

    @PostMapping("/login")
    public void login(@ModelAttribute UserForm user, HttpServletRequest request, HttpServletResponse response) throws IOException {
        request.getSession().setAttribute(LoginFilter.USER_INFO, user);
        String ticket = UUID.randomUUID().toString();
        redisTemplate.opsForValue().set(ticket, user, 20, TimeUnit.SECONDS);
        // redirect logic omitted
    }
}

Login filter handling tickets:

public class SSOFilter implements Filter {
    private RedisTemplate redisTemplate;
    public static final String USER_INFO = "user";
    // init omitted
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        Object userInfo = request.getSession().getAttribute(USER_INFO);
        String requestUrl = request.getServletPath();
        if (!"/toLogin".equals(requestUrl) && !requestUrl.startsWith("/login") && userInfo == null) {
            String ticket = request.getParameter("ticket");
            if (ticket != null) {
                userInfo = redisTemplate.opsForValue().get(ticket);
                if (userInfo != null) {
                    request.getSession().setAttribute(USER_INFO, userInfo);
                    redisTemplate.delete(ticket);
                }
            }
            if (userInfo == null) {
                response.sendRedirect("http://127.0.0.1:8080/toLogin?url=" + request.getRequestURL());
                return;
            }
        }
        chain.doFilter(request, response);
    }
    // destroy omitted
}

CAS vs. OAuth2

CAS is a web‑based SSO framework that authenticates users for multiple web applications, while OAuth2 is an authorization protocol that allows third‑party apps to access a user’s resources without exposing credentials. CAS protects client‑side resources; OAuth2 protects server‑side resources.

Conclusion

The article demonstrates how to implement session management and SSO using CAS in a Java backend, compares it with OAuth2, and provides complete code snippets for a working demo.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaSecurityCASSSOSession
Top Architect
Written by

Top Architect

Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.

0 followers
Reader feedback

How this landed with the community

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.