5

शीर्षक के अनुसार जेडीबीसी टोकनस्टोर और डिफॉल्टटोकन सर्विसेज का उपयोग करते समय डुप्लिकेटकेए अपवाद, शीर्षक में उल्लिखित अनुसार, मुझे समस्या का सामना करना पड़ रहा है, जब एक ही क्लाइंट टोकन एंडपॉइंट को समवर्ती रूप से पूछताछ कर रहा है (दो प्रक्रियाएं उसी क्लाइंट के लिए टोकन का अनुरोध करती हैं पहर)।स्प्रिंग ओएथ 2: भारी लोड

प्रमाणन सर्वर के लॉग में संदेश इस प्रकार है:

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 पर ले जाता है। लेकिन यह बग बहुत समय पहले तय किया गया था और मैं स्प्रिंग बूट (v1.4.2) के नवीनतम संस्करण पर हूं।

मेरा अनुमान है कि मैं कुछ गलत कर रहा हूं और DefaultTokenServices में टोकन की पुनर्प्राप्ति लेनदेन में नहीं हो रही है?

उत्तर

1

समस्या DefaultTokenServices पर दौड़ की स्थिति के साथ है।

मुझे एक कामकाज मिला। यह नहीं कह रहा कि यह बहुत खूबसूरत है लेकिन यह काम करता है। विचार TokenEndpoint के आसपास एक एओपी सलाह का उपयोग करके पुनः प्रयास तर्क जोड़ना है:

@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()); 
    } 

} 
+0

क्या आप विस्तृत कर सकते हैं? मुझे एक ही त्रुटि है, मुझे इसकी आवश्यकता क्यों है? मेरे वसंत बूट एप्लिकेशन में मेरे पास नहीं है: '@ Aspect', '@round' और' ProceedingJoinPoint'। मैं एक ही मुद्दे को कैसे हल कर सकता हूं? – BigDong

संबंधित मुद्दे