How to Customize OAuth2 Tokens with Business Data in Spring Security

This article explains how to extend the default OAuth2 token response by embedding business-related fields such as tenant_id, user_id, and username, and walks through the underlying Spring Security code—including the password grant flow, token creation, and enhancement process—illustrated with code snippets and diagrams.

Java Architecture Diary
Java Architecture Diary
Java Architecture Diary
How to Customize OAuth2 Tokens with Business Data in Spring Security

Personalized Token Purpose

The default response from /oauth/token includes only standard fields such as access_token, token_type, refresh_token, expires_in, and scope, without any business‑specific information like user or tenant data.

By extending the token payload to include fields such as tenant_id, license, dept_id, user_id, and username, the system can retrieve user information directly from the authentication endpoint, reducing repeated calls and improving performance.

Password Grant Token Generation – Source Code Analysis

ResourceOwnerPasswordTokenGranter (password grant) extracts the username and password from the request, creates a UsernamePasswordAuthenticationToken, authenticates it, and builds an OAuth2Authentication object.

protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) {
    Map<String, String> parameters = new LinkedHashMap<>(tokenRequest.getRequestParameters());
    String username = parameters.get("username");
    String password = parameters.get("password");
    parameters.remove("password");
    Authentication userAuth = new UsernamePasswordAuthenticationToken(username, password);
    ((AbstractAuthenticationToken) userAuth).setDetails(parameters);
    userAuth = authenticationManager.authenticate(userAuth);
    OAuth2Request storedOAuth2Request = getRequestFactory().createOAuth2Request(client, tokenRequest);
    return new OAuth2Authentication(storedOAuth2Request, userAuth);
}

After obtaining the OAuth2Authentication, AbstractTokenGranter.getAccessToken() is called to create the token using DefaultTokenServices.

protected OAuth2AccessToken getAccessToken(ClientDetails client, TokenRequest tokenRequest) {
    return tokenServices.createAccessToken(getOAuth2Authentication(client, tokenRequest));
}

The core logic of createAccessToken sets default expiration times (12 hours for access tokens, 30 days for refresh tokens) and assembles the OAuth2AccessToken object.

private int refreshTokenValiditySeconds = 60 * 60 * 24 * 30; // 30 days
private int accessTokenValiditySeconds = 60 * 60 * 12; // 12 hours

private OAuth2AccessToken createAccessToken(OAuth2Authentication authentication, OAuth2RefreshToken refreshToken) {
    DefaultOAuth2AccessToken token = new DefaultOAuth2AccessToken(uuid);
    token.setExpiration(Date);
    token.setRefreshToken(refreshToken);
    token.setScope(authentication.getOAuth2Request().getScope());
    return accessTokenEnhancer != null ? accessTokenEnhancer.enhance(token, authentication) : token;
}

The token is then passed to a configured TokenEnhancer, which adds the additional business fields.

public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
    final Map<String, Object> additionalInfo = new HashMap<>(8);
    PigxUser pigxUser = (PigxUser) authentication.getUserAuthentication().getPrincipal();
    additionalInfo.put("user_id", pigxUser.getId());
    additionalInfo.put("username", pigxUser.getUsername());
    additionalInfo.put("dept_id", pigxUser.getDeptId());
    additionalInfo.put("tenant_id", pigxUser.getTenantId());
    additionalInfo.put("license", SecurityConstants.PIGX_LICENSE);
    ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo);
    return accessToken;
}

Result Demonstration with Pig Platform

Pig is a Spring Cloud‑based, Vue front‑end separated development platform that supports multiple login methods such as account, SMS, and SSO, and provides video tutorials.

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.

AuthenticationOAuth2spring-securityToken Customization
Java Architecture Diary
Written by

Java Architecture Diary

Committed to sharing original, high‑quality technical articles; no fluff or promotional content.

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.