10

प्रति 4.3 साख मैं कम से एक को पचाने प्रमाणीकरण उदाहरण के लिए एक नज़र होने दिया गया है: मेरे परिदृश्य मेंअपाचे HTTP ग्राहक के अनुरोध

http://hc.apache.org/httpcomponents-client-4.3.x/examples.html

कई धागे HTTP अनुरोध जारी करने के देखते हैं और उनमें से प्रत्येक हो गया है प्रमाण पत्र के अपने सेट के साथ प्रमाणित। इसके अतिरिक्त, कृपया इस सवाल को अपाचे HTTP क्लाइंट 4.3 के बाद शायद बहुत विशिष्ट है, 4.2 अलग-अलग तरीके से प्रमाणीकरण संभालता है, हालांकि मैंने इसे स्वयं नहीं देखा है। उस ने कहा, वास्तविक सवाल चला जाता है।

मैं केवल एक क्लाइंट इंस्टेंस (क्लास का स्थिर सदस्य, जो थ्रेडसेफ है) का उपयोग करना चाहता हूं और कई समवर्ती अनुरोधों का समर्थन करने के लिए इसे एक कनेक्शन मैनेजर देना चाहता हूं। मुद्दा यह है कि प्रत्येक अनुरोध अलग-अलग प्रमाण-पत्र प्रदान करेगा और मैं प्रति अनुरोध प्रमाण पत्र असाइन करने का तरीका नहीं देख रहा हूं क्योंकि http क्लाइंट बनाने के दौरान प्रमाण-पत्र प्रदाता सेट किया गया है। ऊपर के लिंक से:

[...]

HttpHost targetHost = new HttpHost("localhost", 80, "http"); 
    CredentialsProvider credsProvider = new BasicCredentialsProvider(); 
    credsProvider.setCredentials(
      new AuthScope(targetHost.getHostName(), targetHost.getPort()), 
      new UsernamePasswordCredentials("username", "password")); 
    CloseableHttpClient httpclient = HttpClients.custom() 
      .setDefaultCredentialsProvider(credsProvider).build(); 

[...]

जाँच:

http://hc.apache.org/httpcomponents-client-ga/tutorial/html/authentication.html#d5e600

बिंदु 4.4 में कोड नमूना (की तलाश 4.4। HTTP प्रमाणीकरण और निष्पादन संदर्भ), ऐसा लगता है कि HttpClientContext को ऑथ कैश और क्रेडिटेंट दिया गया है als प्रदाता और फिर HTTP अनुरोध को पास कर दिया गया है। इसके आगे अनुरोध निष्पादित किया गया है और ऐसा लगता है कि क्लाइंट को HTTP अनुरोध में मेजबान द्वारा फ़िल्टर करने वाले प्रमाण-पत्र प्राप्त होंगे। दूसरे शब्दों में: यदि संदर्भ (या कैश) के पास वर्तमान HTTP अनुरोध के लक्षित होस्ट के लिए वैध प्रमाण-पत्र हैं, तो वह उनका उपयोग करेगा। मेरे लिए समस्या यह है कि अलग-अलग धागे एक ही मेजबान के लिए अलग-अलग अनुरोध करेंगे।

क्या HTTP अनुरोध प्रति कस्टम क्रेडेंशियल प्रदान करने का कोई तरीका है?

आपके समय के लिए अग्रिम धन्यवाद! :)

+0

संभावित डुप्लिकेट [httpclient 4.x] के साथ एक अनुरोध को प्रमाणित करना (http://stackoverflow.com/questions/2516345/authenticating-a-single-request-with-httpclient-4-x) – davidwebster48

उत्तर

13

मेरे लिए समस्या यह है कि अलग-अलग धागे एक ही मेजबान के लिए अलग-अलग अनुरोध करेंगे।

यह समस्या क्यों होनी चाहिए? जब तक आप धागा प्रति एक अलग HttpContext उदाहरण का उपयोग, उन धागे के निष्पादन संदर्भों पूरी तरह से indepenent

CloseableHttpClient httpclient = HttpClients.createDefault(); 
CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); 
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("user:pass")); 
HttpClientContext localContext = HttpClientContext.create(); 
localContext.setCredentialsProvider(credentialsProvider); 

HttpGet httpget = new HttpGet("http://localhost/"); 

CloseableHttpResponse response = httpclient.execute(httpget, localContext); 
try { 
    EntityUtils.consume(response.getEntity()); 
} finally { 
    response.close(); 
} 
+0

क्षमा करें, मेरा सवाल अपरिहार्य था: _ मेरे लिए समस्या यह है कि अलग-अलग प्रमाण-पत्रों के साथ अलग-अलग धागे ** प्रत्येक मेजबान के लिए अनुरोध करेगा। _ तो, केवल एक क्लाइंट और सभी धागे के लिए केवल एक प्रमाण पत्र प्रदाता उदाहरण है (प्रत्येक थ्रेड इसके क्रेडेंशियल्स में रखेगा) और एक थ्रेड प्रति संदर्भ, कैसे (केवल) क्लाइंट जानता है कि प्रत्येक थ्रेड के लिए किस क्रेडेंशियल्स का उपयोग करना है ??? अग्रिम में आपके समय के लिए धन्यवाद! –

+0

@ फ्रांसिस्को कैरिडोशेर: मुझे यकीन नहीं है कि मैं यहां जो कठिनाई कर रहा हूं उसे समझता हूं। बिल्कुल कुछ भी नहीं है जो आपको प्रति थ्रेड/संदर्भ – oleg

+0

पर एक अलग प्रमाण-पत्र प्रदाता होने से रोकता है, सभी थ्रेडों के लिए एक एकल प्रमाण पत्र प्रदाता को पकड़ना मुश्किल था (जैसा कि यह आंतरिक रूप से प्रमाण-पत्रों के सेट को प्रबंधित करने के लिए तैयार किया जाता है), लेकिन अंत में ऐसा लगता है कि, कम से कम BasicCredentialsProvider प्रति उदाहरण केवल एक प्रमाण पत्र प्रबंधित करता है। तो, प्रति थ्रेड एक नया क्रेडेंशियल प्रदाता उदाहरण का उपयोग करने का तरीका लगता है और आपका उदाहरण ठीक काम करता है। –

0

मैं एक ऐसी ही समस्या आ रही है होने जा रहे हैं।

मुझे एनटीएलएम के साथ प्रमाणित एक सिस्टम सिस्टम के साथ एन-बार सेवा को कॉल करना होगा। मैं इसे कई धागे का उपयोग करके करना चाहता हूं। जो मैं आया था वह एक एकल HTTP क्लाइंट बना रहा है जिसमें कोई डिफ़ॉल्ट क्रेडेंशियल प्रदाता नहीं है। जब एक अनुरोध करने की आवश्यकता होती है तो मैं अनुरोध करने वाले विधि (एक विशिष्ट थ्रेड में) में एक इंजेक्शन CredentialProviderFactory का उपयोग करता हूं। इसका उपयोग करके मुझे एक नया नया प्रमाण पत्रप्रदाता मिल गया है और मैंने इसे एक संदर्भ (थ्रेड में बनाया गया) में रखा है। फिर मैं ओवरलोड execute(method, context) का उपयोग कर क्लाइंट पर निष्पादन विधि को कॉल करता हूं।

class MilestoneBarClient implements IMilestoneBarClient { 

private static final Logger log = LoggerFactory.getLogger(MilestoneBarClient.class); 
private MilestoneBarBuilder builder; 
private CloseableHttpClient httpclient; 
private MilestoneBarUriBuilder uriBuilder; 
private ICredentialsProviderFactory credsProviderFactory; 


MilestoneBarClient(CloseableHttpClient client, ICredentialsProviderFactory credsProviderFactory, MilestoneBarUriBuilder uriBuilder) { 
    this(client, credsProviderFactory, uriBuilder, new MilestoneBarBuilder()); 
} 

MilestoneBarClient(CloseableHttpClient client, ICredentialsProviderFactory credsProviderFactory, MilestoneBarUriBuilder uriBuilder, MilestoneBarBuilder milestoneBarBuilder) { 
    this.credsProviderFactory = credsProviderFactory; 
    this.uriBuilder = uriBuilder; 
    this.builder = milestoneBarBuilder; 
    this.httpclient = client; 
} 

// This method is called by multiple threads 
@Override 
public MilestoneBar get(String npdNumber) { 
    log.debug("Asking milestone bar info for {}", npdNumber); 

    try { 
     String url = uriBuilder.getPathFor(npdNumber); 
     log.debug("Building request for URL {}", url); 
     HttpClientContext localContext = HttpClientContext.create(); 
     localContext.setCredentialsProvider(credsProviderFactory.create()); 

     HttpGet httpGet = new HttpGet(url); 

     long start = System.currentTimeMillis(); 
     try(CloseableHttpResponse resp = httpclient.execute(httpGet, localContext)){ 
[...] 

कुछ कारणों से मैं कभी कभी कोई त्रुटि मिलती है, लेकिन मुझे लगता है कि यह एक NTLMCredentials मुद्दा (... धागा सुरक्षित नहीं किया जा रहा) है।

अपने मामले में, आप संभवतः कारखाने को सृजन में गुजरने के बजाय प्राप्त विधियों को पारित कर सकते हैं।

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