Implementing Single Sign-On with Spring Security and JWT

This article provides a comprehensive 20,000‑word guide on building a Spring Security‑based single sign‑on solution using JWT, covering the SSO concept, token structure, RSA encryption, Maven project setup, configuration files, custom authentication and verification filters, and end‑to‑end testing with Postman.

Top Architect
Top Architect
Top Architect
Implementing Single Sign-On with Spring Security and JWT

In this tutorial the author, a senior architect, explains how to implement Single Sign‑On (SSO) using Spring Security combined with JSON Web Tokens (JWT). The article begins with a definition of SSO and a simple real‑world analogy of a park ticket system to illustrate the authentication and token verification flow.

JWT Overview

JWT (JSON Web Token) is introduced as a lightweight, distributed identity verification solution. Its three parts—header, payload, and signature—are described, and the security implications of each part are analyzed, emphasizing the need for asymmetric RSA encryption to protect the signing secret.

RSA Asymmetric Encryption

The basics of RSA are covered, including key pair generation, public‑key encryption, private‑key decryption, and the advantages and drawbacks of the algorithm. Sample code for generating RSA keys and reading them from files is provided.

public class RsaUtils {
    private static final int DEFAULT_KEY_SIZE = 2048;
    public static PublicKey getPublicKey(String filename) throws Exception { ... }
    public static PrivateKey getPrivateKey(String filename) throws Exception { ... }
    public static void generateKey(String pubFile, String priFile, String secret, int keySize) throws Exception { ... }
}

Project Structure

A Maven multi‑module project is created with a parent pom, a common module for shared utilities (including JWT and RSA helpers), an authentication service, and a resource service. The pom snippets for dependencies such as jjwt, spring‑boot‑starter‑security, and mybatis‑spring‑boot‑starter are shown.

Configuration Files

Spring Boot configuration (application.yml) defines the datasource, MyBatis settings, logging, and RSA key file locations. A configuration class loads the RSA public and private keys at startup.

@ConfigurationProperties(prefix = "rsa.key")
public class RsaKeyProperties {
    private String pubKeyFile;
    private String priKeyFile;
    private PublicKey publicKey;
    private PrivateKey privateKey;
    @PostConstruct
    public void createRsaKey() throws Exception { ... }
}

Domain Model

Two POJOs are defined: RolePojo implements GrantedAuthority, and UserPojo implements UserDetails. They provide user information and authorities required by Spring Security.

Data Access Layer

MyBatis mapper interfaces and XML files are used to query user data from a MySQL database.

Custom Authentication Filter

A TokenLoginFilter extends UsernamePasswordAuthenticationFilter to read JSON login requests, authenticate via AuthenticationManager, and generate a JWT token on success. The token is added to the response header Authorization: Bearer <token>.

public void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) {
    UserPojo user = new UserPojo();
    user.setUsername(authResult.getName());
    String token = JwtUtils.generateTokenExpireInMinutes(user, prop.getPrivateKey(), 24 * 60);
    response.addHeader("Authorization", "Bearer " + token);
    // write JSON success body
}

Token Verification Filter

A TokenVerifyFilter extends BasicAuthenticationFilter to extract the JWT from the Authorization header, validate it with the RSA public key, reconstruct the UserPojo, and set the authentication in the security context.

Payload<UserPojo> payload = JwtUtils.getInfoFromToken(token, prop.getPublicKey(), UserPojo.class);
UserPojo user = payload.getUserInfo();
if (user != null) {
    UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(user.getUsername(), null, user.getAuthorities());
    SecurityContextHolder.getContext().setAuthentication(auth);
}

Spring Security Configuration

The WebSecurityConfig class disables CSRF, configures method security, registers the custom filters, and enforces stateless session management. The authentication manager uses the UserService (which implements UserDetailsService) and a BCrypt password encoder.

Resource Service

A second microservice (resource service) is created that only holds the RSA public key and validates incoming JWTs; it does not issue tokens. The same domain classes and security filter are reused, but the login filter is omitted.

Testing

The services are started, and Postman is used to perform a login request, retrieve the JWT, and call protected endpoints (e.g., /user/query) with the token. Screenshots illustrate the successful responses.

Finally, the author promotes a “BAT” interview question collection and a WeChat group for architecture enthusiasts, encouraging readers to reply with keywords to receive additional resources.

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.

JavaAuthenticationJWTSSOspring-security
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.