Spring-boot 资源服务器仅在过期时验证令牌
Posted
技术标签:
【中文标题】Spring-boot 资源服务器仅在过期时验证令牌【英文标题】:Spring-boot Resource server validate token only when expired 【发布时间】:2021-06-04 13:16:48 【问题描述】:我正在使用spring-boot开发一个微服务结构,这个结构有一个外部的oauth2授权服务器和多个资源服务器。
我的问题是,对我的资源的每个 http 请求都会调用我的授权服务器的 url,以验证令牌 (.../oauth/check_token/
)。这种方式有很多请求。有一种方法可以仅在过期时验证/检查此令牌?
我的资源服务器:
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter
@Value("$security.oauth2.client.client-id")
private String clientId;
@Value("$security.oauth2.client.client-secret")
private String clientSecret;
@Value("$security.oauth2.resource.id")
private String resourceId;
@Value("$security.oauth2.resource.token-info-uri")
private String tokenInfoUri;
@Override
public void configure(HttpSecurity http) throws Exception
http
.authorizeRequests()
.antMatchers(ADMIN_ANT_MATCHER).hasRole("ADMIN")
.antMatchers(PROTECTED_ANT_MATCHER).hasRole("USER")
.and()
.csrf().disable();
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception
resources.tokenServices(tokenService()).resourceId(resourceId).stateless(true);
@Bean
@Primary
public RemoteTokenServices tokenService()
RemoteTokenServices tokenService = new RemoteTokenServices();
tokenService.setCheckTokenEndpointUrl(tokenInfoUri);
tokenService.setClientId(clientId);
tokenService.setClientSecret(clientSecret);
return tokenService;
授权服务器:
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter
@Value("$security.oauth2.client.client-id")
private String clientId;
@Value("$security.oauth2.client.client-secret")
private String clientSecret;
@Value("$security.oauth2.resource.id")
private String resourceId;
@Value("$security.oauth2.client.access-token-validity-seconds")
private Integer tokenValidateSeconds;
@Value("$security.oauth2.client.token-secret")
private String tokenSecret;
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private TokenStore tokenStore;
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private OauthAccessTokenRepository oauthAccessTokenRepository;
@Autowired
private OauthRefreshTokenRepository oauthRefreshTokenRepository;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception
endpoints
.tokenStore(this.tokenStore)
.tokenEnhancer(tokenEnhancer())
.authenticationManager(this.authenticationManager)
.userDetailsService(userDetailsService);
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception
clients
.inMemory()
.withClient(clientId)
.authorizedGrantTypes("client_credentials", "password", "refresh_token")
.authorities("ROLE_USER","ROLE_ADMIN")
.scopes("read","write","trust")
.resourceIds(resourceId)
.accessTokenValiditySeconds(tokenValidateSeconds)
.secret(bCryptPasswordEncoder().encode(clientSecret));
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception
security.checkTokenAccess("isAuthenticated()");
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder()
return new BCryptPasswordEncoder();
@Bean
@Primary
public DefaultTokenServices tokenServices()
DefaultTokenServices tokenServices = new DefaultTokenServices();
tokenServices.setSupportRefreshToken(true);
tokenServices.setTokenStore(this.tokenStore);
return tokenServices;
@Bean
public TokenEnhancer tokenEnhancer()
return new TokenEnhancer()
@Override
public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication)
CustomUser user = (CustomUser) authentication.getPrincipal();
String token = JwtTokenHelper.generateToken(
user.getIdUser(),
user.getTenantID(),
user.getIdEntity(),
user.getIdBusinessUnit(),
user.getProfile(),
tokenValidateSeconds,
tokenSecret
);
((DefaultOAuth2AccessToken) accessToken).setValue(token);
return accessToken;
;
【问题讨论】:
【参考方案1】:您可以通过使用签名的JWT 令牌消除使用check_token endpoint 的需要。
当资源服务器收到 JWT 令牌时,它会使用公钥验证其签名,并通过检查 JSON 对象中的相应字段来验证其到期日期。
为此,您可以使用JwtAccessTokenConverter、JwtTokenStore 和nimbus-jose-jwt 库。
这种方法的缺点是您无法撤销令牌。那么最好有短暂的令牌。
【讨论】:
我确实按照你说的做,并且按预期工作,我也意识到性能应用比以前更好,谢谢你的帮助!以上是关于Spring-boot 资源服务器仅在过期时验证令牌的主要内容,如果未能解决你的问题,请参考以下文章
Spring-Boot 仅在一个配置文件中执行 data.sql