Spring Security返回值扩展自定义字段

作者
2025-09-25阅读 31

1、需求

当前的获取token只返回了accessToken,refreshToken,expiresIn3个字段。

由于我现在要在前端进行一些token过期的验证,所以我想要在返回值中返回过期时间(具体的毫秒数)。

2、实现方式

我的实现前提:我的返回值是继承了AuthenticationSuccessHandler,但是实际使用的依然还是OAuth2AccessTokenResponse

可以看到OAuth2AccessTokenResponse这个类,里面有一个变量:additionalParameters

null

我们用的就是这个变量。这个变量是Map,可以把我们想要扩展的字段都放到这里面

3、具体的实现

关键的代码

Map<String, Object> additionalParameters = accessTokenAuthentication.getAdditionalParameters();

tokenResponseParameters.put("refresh_expires_in", ChronoUnit.SECONDS.between(refreshToken.getIssuedAt(), refreshToken.getExpiresAt()));

tokenResponseParameters.put("refresh_expires_at", refreshToken.getExpiresAt().toEpochMilli());

builder.additionalParameters(additionalParameters);

	private void sendAccessTokenResponse(HttpServletResponse response, Authentication authentication)
			throws IOException {

		//扩展默认行为,使用自定义的 Map<String, Object> 存储额外参数
		Map<String, Object> tokenResponseParameters = new HashMap<String, Object>();

		OAuth2AccessTokenAuthenticationToken accessTokenAuthentication = (OAuth2AccessTokenAuthenticationToken) authentication;

		OAuth2AccessToken accessToken = accessTokenAuthentication.getAccessToken();
		OAuth2RefreshToken refreshToken = accessTokenAuthentication.getRefreshToken();
		Map<String, Object> additionalParameters = accessTokenAuthentication.getAdditionalParameters();

		OAuth2AccessTokenResponse.Builder builder = OAuth2AccessTokenResponse.withToken(accessToken.getTokenValue())
				.tokenType(accessToken.getTokenType()).scopes(accessToken.getScopes());
		if (accessToken.getIssuedAt() != null && accessToken.getExpiresAt() != null) {
			builder.expiresIn(ChronoUnit.SECONDS.between(accessToken.getIssuedAt(), accessToken.getExpiresAt()));
			tokenResponseParameters.put("expires_at", accessToken.getExpiresAt().toEpochMilli());
		}
		if (refreshToken != null) {
			builder.refreshToken(refreshToken.getTokenValue());
			tokenResponseParameters.put("refresh_expires_in", ChronoUnit.SECONDS.between(refreshToken.getIssuedAt(), refreshToken.getExpiresAt()));
			tokenResponseParameters.put("refresh_expires_at", refreshToken.getExpiresAt().toEpochMilli());
		}
		if (!CollectionUtils.isEmpty(additionalParameters)) {
			builder.additionalParameters(additionalParameters);
		}
		OAuth2AccessTokenResponse accessTokenResponse = builder.additionalParameters(tokenResponseParameters).build();
		ServletServerHttpResponse httpResponse = new ServletServerHttpResponse(response);

		// 无状态 注意删除 context 上下文的信息
		SecurityContextHolder.clearContext();
		this.accessTokenHttpResponseConverter.write(accessTokenResponse, null, httpResponse);
	}



全部评论

头像
乌兔
前端开发
私信
获得点赞 445
文章被阅读 31,261