gpt4 book ai didi

Spring OAuth2 : DuplicateKeyException when using JdbcTokenStore and DefaultTokenServices under heavy load

转载 作者:行者123 更新时间:2023-12-04 08:22:04 50 4
gpt4 key购买 nike

正如标题中提到的,当同一个客户端同时查询 token 端点时(两个进程同时为同一个客户端请求 token ),我遇到了这个问题。

身份验证服务器日志中的消息如下所示:

2016-12-05 19:08:03.313  INFO 31717 --- [nio-9999-exec-5] o.s.s.o.provider.endpoint.TokenEndpoint  : Handling error: DuplicateKeyException, PreparedStatementCallback; SQL [insert into oauth_access_token (token_id, token, authentication_id, user_name, client_id, authentication, refresh_token) values (?, ?, ?, ?, ?, ?, ?)]; ERROR: duplicate key value violates unique constraint "oauth_access_token_pkey"
Detail: Key (authentication_id)=(4148f592d600ab61affc6fa90bcbf16f) already exists.; nested exception is org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "oauth_access_token_pkey"
Detail: Key (authentication_id)=(4148f592d600ab61affc6fa90bcbf16f) already exists.

我将 PostgreSQL 与这样的表一起使用:
CREATE TABLE oauth_access_token
(
token_id character varying(256),
token bytea,
authentication_id character varying(256) NOT NULL,
user_name character varying(256),
client_id character varying(256),
authentication bytea,
refresh_token character varying(256),
CONSTRAINT oauth_access_token_pkey PRIMARY KEY (authentication_id)
)

我的应用程序看起来像这样:
@SpringBootApplication
public class OAuthServTest {
public static void main (String[] args) {
SpringApplication.run (OAuthServTest.class, args);
}

@Configuration
@EnableAuthorizationServer
@EnableTransactionManagement
protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter {

@Autowired
private AuthenticationManager authenticationManager;

@Autowired
private DataSource dataSource;

@Bean
public PasswordEncoder passwordEncoder ( ) {
return new BCryptPasswordEncoder ( );
}

@Override
public void configure (AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager (authenticationManager);
endpoints.tokenServices (tokenServices ( ));
}

@Override
public void configure (ClientDetailsServiceConfigurer clients) throws Exception {
clients.jdbc (this.dataSource).passwordEncoder (passwordEncoder ( ));
}

@Override
public void configure (AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.passwordEncoder (passwordEncoder ( ));
}

@Bean
public TokenStore tokenStore ( ) {
return new JdbcTokenStore (this.dataSource);
}

@Bean
@Primary
public AuthorizationServerTokenServices tokenServices ( ) {
final DefaultTokenServices defaultTokenServices = new DefaultTokenServices ( );
defaultTokenServices.setTokenStore (tokenStore ( ));
return defaultTokenServices;
}

}
}

我的研究总是把我带到 this problem .但是这个错误很久以前就被修复了,我使用的是最新版本的 Spring Boot (v1.4.2)。

我的猜测是我做错了什么并且检索了 DefaultTokenServices 中的 token 是不是在交易中发生?

最佳答案

问题在于 DefaultTokenServices 上的竞争条件.

我找到了一个解决方法。不是说它华丽,但它有效。这个想法是使用围绕 TokenEndpoint 的 AOP 建议添加重试逻辑。 :

@Aspect
@Component
public class TokenEndpointRetryInterceptor {

private static final int MAX_RETRIES = 4;

@Around("execution(* org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.*(..))")
public Object execute (ProceedingJoinPoint aJoinPoint) throws Throwable {
int tts = 1000;
for (int i=0; i<MAX_RETRIES; i++) {
try {
return aJoinPoint.proceed();
} catch (DuplicateKeyException e) {
Thread.sleep(tts);
tts=tts*2;
}
}
throw new IllegalStateException("Could not execute: " + aJoinPoint.getSignature().getName());
}

}

关于 Spring OAuth2 : DuplicateKeyException when using JdbcTokenStore and DefaultTokenServices under heavy load,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40981084/

50 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com