You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Authorization Server能否按授权类型设置不同令牌有效期?

按授权类型设置不同的Access Token有效期

当然可以实现,以下是两种常用的解决方案:

方法一:自定义TokenServices(推荐)

通过继承DefaultTokenServices并重写getAccessTokenValiditySeconds方法,根据授权类型返回对应的有效期:

import org.springframework.security.oauth2.provider.OAuth2Request;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;

public class CustomTokenServices extends DefaultTokenServices {

    // 配置client_credentials类型令牌的有效期(1天)
    private int clientCredentialsTokenValiditySeconds = 86400;
    // 配置password类型令牌的有效期(5分钟)
    private int passwordTokenValiditySeconds = 300;

    @Override
    protected int getAccessTokenValiditySeconds(OAuth2Request clientAuth) {
        String grantType = clientAuth.getGrantType();
        if ("client_credentials".equals(grantType)) {
            return clientCredentialsTokenValiditySeconds;
        } else if ("password".equals(grantType)) {
            return passwordTokenValiditySeconds;
        }
        // 其他授权类型沿用默认配置
        return super.getAccessTokenValiditySeconds(clientAuth);
    }

    // 提供setter方法用于外部配置
    public void setClientCredentialsTokenValiditySeconds(int clientCredentialsTokenValiditySeconds) {
        this.clientCredentialsTokenValiditySeconds = clientCredentialsTokenValiditySeconds;
    }

    public void setPasswordTokenValiditySeconds(int passwordTokenValiditySeconds) {
        this.passwordTokenValiditySeconds = passwordTokenValiditySeconds;
    }
}

然后在授权服务器配置中替换默认的TokenServices:

@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
    CustomTokenServices tokenServices = new CustomTokenServices();
    tokenServices.setTokenStore(endpoints.getTokenStore());
    tokenServices.setSupportRefreshToken(true);
    tokenServices.setClientDetailsService(endpoints.getClientDetailsService());
    // 自定义有效期
    tokenServices.setClientCredentialsTokenValiditySeconds(86400);
    tokenServices.setPasswordTokenValiditySeconds(300);

    endpoints.tokenServices(tokenServices);
}

方法二:使用TokenEnhancer修改令牌过期时间

通过实现TokenEnhancer接口,在令牌生成阶段根据授权类型调整过期时间:

import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class CustomTokenEnhancer implements TokenEnhancer {

    private int clientCredentialsTokenValiditySeconds = 86400;
    private int passwordTokenValiditySeconds = 300;

    @Override
    public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
        String grantType = authentication.getOAuth2Request().getGrantType();
        int validitySeconds = passwordTokenValiditySeconds;

        if ("client_credentials".equals(grantType)) {
            validitySeconds = clientCredentialsTokenValiditySeconds;
        }

        // 设置令牌过期时间
        ((DefaultOAuth2AccessToken) accessToken).setExpiration(
                new Date(System.currentTimeMillis() + (validitySeconds * 1000L))
        );

        // 可选:添加授权类型到令牌附加信息
        Map<String, Object> additionalInfo = new HashMap<>();
        additionalInfo.put("grant_type", grantType);
        ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo);

        return accessToken;
    }

    public void setClientCredentialsTokenValiditySeconds(int clientCredentialsTokenValiditySeconds) {
        this.clientCredentialsTokenValiditySeconds = clientCredentialsTokenValiditySeconds;
    }

    public void setPasswordTokenValiditySeconds(int passwordTokenValiditySeconds) {
        this.passwordTokenValiditySeconds = passwordTokenValiditySeconds;
    }
}

在授权服务器配置中添加令牌增强链:

import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;
import java.util.Arrays;

@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
    CustomTokenEnhancer tokenEnhancer = new CustomTokenEnhancer();
    tokenEnhancer.setClientCredentialsTokenValiditySeconds(86400);
    tokenEnhancer.setPasswordTokenValiditySeconds(300);

    TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
    enhancerChain.setTokenEnhancers(Arrays.asList(tokenEnhancer, endpoints.getTokenEnhancer()));

    endpoints.tokenEnhancer(enhancerChain);
}

注意事项

  • 两种方法都能实现需求,自定义TokenServices更贴近框架核心逻辑,会同时影响令牌存储中的有效期校验;TokenEnhancer则是在令牌生成后修改过期时间,适合快速调整。
  • 原配置中的accessTokenValiditySeconds会作为默认值,当授权类型不匹配自定义规则时生效。

内容的提问来源于stack exchange,提问作者Lyle Phillips

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 03:00:53