HttpClient का उपयोग करके जावा में Http मूल प्रमाणीकरण?


156

मैं जावा में इस कर्ल कमांड की कार्यक्षमता की नकल करने की कोशिश कर रहा हूं:

curl --basic --user username:password -d "" http://ipaddress/test/login

मैंने कॉमन्स HttpClient 3.0 का उपयोग करते हुए निम्नलिखित लिखा था, लेकिन किसी तरह 500 Internal Server Errorसर्वर से प्राप्त करना समाप्त कर दिया । क्या कोई मुझे बता सकता है कि क्या मैं कुछ गलत कर रहा हूं?

public class HttpBasicAuth {

    private static final String ENCODING = "UTF-8";

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        try {

            HttpClient client = new HttpClient();

            client.getState().setCredentials(
                    new AuthScope("ipaddress", 443, "realm"),
                    new UsernamePasswordCredentials("test1", "test1")
                    );

            PostMethod post = new PostMethod(
                    "http://address/test/login");

            post.setDoAuthentication( true );

            try {
                int status = client.executeMethod( post );
                System.out.println(status + "\n" + post.getResponseBodyAsString());
            } finally {
                // release any connection resources used by the method
                post.releaseConnection();
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
   } 

और मैंने बाद में एक कॉमन्स HttpClient 4.0.1 की कोशिश की, लेकिन अभी भी वही त्रुटि है:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;


public class HttpBasicAuth {

    private static final String ENCODING = "UTF-8";

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub

        try {
            DefaultHttpClient httpclient = new DefaultHttpClient();

            httpclient.getCredentialsProvider().setCredentials(
                    new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT), 
                    new UsernamePasswordCredentials("test1", "test1"));

            HttpPost httppost = new HttpPost("http://host:post/test/login");

            System.out.println("executing request " + httppost.getRequestLine());
            HttpResponse response;
            response = httpclient.execute(httppost);
            HttpEntity entity = response.getEntity();

            System.out.println("----------------------------------------");
            System.out.println(response.getStatusLine());
            if (entity != null) {
                System.out.println("Response content length: " + entity.getContentLength());
            }
            if (entity != null) {
                entity.consumeContent();
            }

            httpclient.getConnectionManager().shutdown();  
        } catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
}

उम, सर्वर लॉग में दिखाई देने वाली त्रुटि क्या है?
hvgotcodes

आह ... मेरे पास सर्वर लॉग्स का उपयोग नहीं है :(
लेजेंड

अधिकांश समय प्राधिकरण कुंजी जिसका हम उपयोग कर रहे हैं वह गलत हो सकती है। जाँचें dev.tapjoy.com/faq/how-to-find-sender-id-and-ap-key-for-gcm यह देखने के लिए कि आप सही कुंजी का उपयोग कर रहे हैं या नहीं। फायरबेस के लिए एपीआई कुंजी का चयन करते समय मैं भी भ्रमित हो गया था हमें फायरबेस सेटिंग के तहत क्लाउड मैसेजिंग टैब में सेंडर आईडी - एपीआई कुंजी जोड़ी का उपयोग करना होगा। यानी फायरबस ऐप पर जाएं -> ऐप सेटिंग पर जाएं -> क्लाउड मैसेजिंग वहां आप सेंडर आईडी <==> एपीआई कुंजी और यह एपीआई कुंजी पा सकते हैं जिसका उपयोग आप एफसीएम भेजने के लिए कर सकते हैं।
राहुल

जवाबों:


187

क्या आपने यह कोशिश की है (HttpClient संस्करण 4 का उपयोग करके):

String encoding = Base64Encoder.encode(user + ":" + pwd);
HttpPost httpPost = new HttpPost("http://host:post/test/login");
httpPost.setHeader(HttpHeaders.AUTHORIZATION, "Basic " + encoding);

System.out.println("executing request " + httpPost.getRequestLine());
HttpResponse response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity();

64
java.util.Base64जावा 8 के रूप में उपयोग करने के लिए बेहतर :Base64.getEncoder().encodeToString(("test1:test1").getBytes());
माइकल बेरी

1
मैं javax.xml.bind.DatatypeConverter को बेस 64, हेक्स और अन्य रूपांतरण में बदलना पसंद करता हूं। यह jdk का एक हिस्सा है इसलिए किसी भी अतिरिक्त जार को शामिल करने की आवश्यकता नहीं है।
मुबाशर

1
यह मेरे उपयोग के मामले में मेरे लिए कार्य करता है जहां HttpClient पहले से ही उपलब्ध है और आप httpclient का निर्माण करते समय बिल्डर पर setDefaultCredentialsProvider () सेट नहीं कर सकते हैं। इसके अलावा मुझे यह पसंद है क्योंकि यह प्रति कॉल स्कोप है। पूरे httpclient के दायरे में नहीं।
टोनी

114

ठीक है तो यह काम करता है बस अगर कोई इसे चाहता है, तो यहां वह संस्करण है जो मेरे लिए काम करता है :)

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Base64;


public class HttpBasicAuth {

    public static void main(String[] args) {

        try {
            URL url = new URL ("http://ip:port/login");
            String encoding = Base64.getEncoder().encodeToString(("test1:test1").getBytes(‌"UTF‌​-8"​));

            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("POST");
            connection.setDoOutput(true);
            connection.setRequestProperty  ("Authorization", "Basic " + encoding);
            InputStream content = (InputStream)connection.getInputStream();
            BufferedReader in   = 
                new BufferedReader (new InputStreamReader (content));
            String line;
            while ((line = in.readLine()) != null) {
                System.out.println(line);
            }
        } catch(Exception e) {
            e.printStackTrace();
        }

    }

}

4
नहीं मिल रहा Base64Encoder। जोनास क्या आप पूर्ण जार दे सकते हैं? इसके अलावा पूरी तरह से योग्य वर्ग का नाम क्या है Base64Encoder?
जुस

@ अमितभ: यहांBase64Encoder देखने के लिए । के लिए पर 4.2.5.zip में कॉमन्स-कोडेक-1.6.jar में नज़र अपाचे HttpComponents डाउनलोड , डॉक ,Base64import org.apache.commons.codec.binary.Base64;
Lernkurve

22
इस सवाल का जवाब नहीं है। प्रश्न HttpClient का उपयोग करने के बारे में पूछता है और यह उत्तर HttpClient का उपयोग नहीं करता है।
पॉल क्रॉकरिन

9
यदि आप जावा 8 का उपयोग कर रहे हैं, तो आप java.util.Base64 का उपयोग कर सकते हैं।
डब्ल्यूडब्ल्यू।

4
यहाँ java.util.Base64 के लिए लाइन हैString encoding = Base64.getEncoder().encodeToString("test1:test1".getBytes("utf-8"));
जो

16

यह ऊपर दिए गए स्वीकृत उत्तर से कोड है, जिसमें बेस 64 एनकोडिंग के संबंध में कुछ बदलाव किए गए हैं। नीचे दिए गए कोड।

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

import org.apache.commons.codec.binary.Base64;


public class HttpBasicAuth {

    public static void main(String[] args) {

        try {
            URL url = new URL ("http://ip:port/login");

            Base64 b = new Base64();
            String encoding = b.encodeAsString(new String("test1:test1").getBytes());

            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("POST");
            connection.setDoOutput(true);
            connection.setRequestProperty  ("Authorization", "Basic " + encoding);
            InputStream content = (InputStream)connection.getInputStream();
            BufferedReader in   = 
                new BufferedReader (new InputStreamReader (content));
            String line;
            while ((line = in.readLine()) != null) {
                System.out.println(line);
            }
        } 
        catch(Exception e) {
            e.printStackTrace();
        }
    }
}

14

एक छोटा सा अद्यतन - किसी के लिए उम्मीद है कि उपयोगी है - यह अपने प्रोजेक्ट में मेरे लिए काम करता है:

  • मैं रॉबर्ट हार्डर (धन्यवाद रॉबर्ट - कोड उपलब्ध यहाँ से अच्छा सार्वजनिक डोमेन वर्ग Base64.java का उपयोग करता हूँ: Base64 - डाउनलोड करें और इसे अपने पैकेज में रखें)।

  • और प्रमाणीकरण के साथ एक फ़ाइल (छवि, डॉक्टर, आदि) का डाउनलोड करें और स्थानीय डिस्क पर लिखें

उदाहरण:

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

public class HttpBasicAuth {

public static void downloadFileWithAuth(String urlStr, String user, String pass, String outFilePath) {
    try {
        // URL url = new URL ("http://ip:port/download_url");
        URL url = new URL(urlStr);
        String authStr = user + ":" + pass;
        String authEncoded = Base64.encodeBytes(authStr.getBytes());

        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("GET");
        connection.setDoOutput(true);
        connection.setRequestProperty("Authorization", "Basic " + authEncoded);

        File file = new File(outFilePath);
        InputStream in = (InputStream) connection.getInputStream();
        OutputStream out = new BufferedOutputStream(new FileOutputStream(file));
        for (int b; (b = in.read()) != -1;) {
            out.write(b);
        }
        out.close();
        in.close();
    }
    catch (Exception e) {
        e.printStackTrace();
    }
}
}

2
मुझे मिलता हैThe method encodeBytes(byte[]) is undefined for the type Base64
फ्रांसिस्को कॉर्लेस मोरालेस

कस्टम बेस 64 वर्ग को इस पृष्ठ पर इस उत्तर में विस्तृतimport org.apache.commons.codec.binary.Base64; रूप से प्रतिस्थापित किया जा सकता है
ब्रैड पार्क्स

3
जावा 8 में, आप उपयोग कर सकते हैं: java.util.Base64 आयात करें;
डब्ल्यूडब्ल्यू।

7

यहाँ कुछ बिंदु दिए गए हैं:

  • आप HttpClient 4 में अपग्रेड करने पर विचार कर सकते हैं (आमतौर पर बोलते हुए, यदि आप कर सकते हैं, मुझे नहीं लगता कि संस्करण 3 अभी भी सक्रिय रूप से समर्थित है)।

  • 500 स्टेटस कोड एक सर्वर त्रुटि है, इसलिए यह देखने के लिए उपयोगी हो सकता है कि सर्वर क्या कहता है (आपके द्वारा प्रिंट किए जा रहे रिस्पांस बॉडी में कोई सुराग?)। यद्यपि यह आपके क्लाइंट के कारण हो सकता है, सर्वर को इस तरह से विफल नहीं होना चाहिए (यदि अनुरोध गलत है तो 4xx त्रुटि कोड अधिक उपयुक्त होगा)।

  • मुझे लगता setDoAuthentication(true)है कि डिफ़ॉल्ट (निश्चित नहीं है)। क्या करने के लिए उपयोगी हो सकता है पूर्व-खाली प्रमाणीकरण बेहतर काम करता है:

    client.getParams().setAuthenticationPreemptive(true);

अन्यथा, curl -d ""जावा में जो आप कर रहे हैं , उसके बीच मुख्य अंतर यह है कि, इसके अलावा Content-Length: 0, कर्ल भी भेजता है Content-Type: application/x-www-form-urlencoded। ध्यान दें कि डिजाइन के संदर्भ में, आपको संभवतः अपने POSTअनुरोध के साथ एक इकाई भेजनी चाहिए ।


5

ऊपर दिए गए सभी उत्तरों के लिए धन्यवाद, लेकिन मेरे लिए, मुझे बेस 64 इनेकोडर वर्ग नहीं मिल सकता है, इसलिए मैं वैसे भी अपना रास्ता निकालता हूं।

public static void main(String[] args) {
    try {
        DefaultHttpClient Client = new DefaultHttpClient();

        HttpGet httpGet = new HttpGet("https://httpbin.org/basic-auth/user/passwd");
        String encoding = DatatypeConverter.printBase64Binary("user:passwd".getBytes("UTF-8"));
        httpGet.setHeader("Authorization", "Basic " + encoding);

        HttpResponse response = Client.execute(httpGet);

        System.out.println("response = " + response);

        BufferedReader breader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
        StringBuilder responseString = new StringBuilder();
        String line = "";
        while ((line = breader.readLine()) != null) {
            responseString.append(line);
        }
        breader.close();
        String repsonseStr = responseString.toString();

        System.out.println("repsonseStr = " + repsonseStr);

    } catch (IOException e) {
        e.printStackTrace();
    }

}

एक और बात, मैंने भी कोशिश की

Base64.encodeBase64String("user:passwd".getBytes());

यह एक स्ट्रिंग के साथ लगभग एक ही वापसी के कारण काम नहीं करता है

DatatypeConverter.printBase64Binary()

लेकिन "\ r \ n" के साथ समाप्त होता है, फिर सर्वर "खराब अनुरोध" लौटाएगा।

साथ ही निम्नलिखित कोड भी काम कर रहा है, वास्तव में मैं इसे पहले सॉर्ट करता हूं, लेकिन किसी कारण से, यह कुछ क्लाउड वातावरण में काम नहीं करता है (sae.sina.com.cn यदि आप जानना चाहते हैं, तो यह एक चीनी क्लाउड सेवा है)। इसलिए HttpClient क्रेडेंशियल्स के बजाय http हेडर का उपयोग करना होगा।

public static void main(String[] args) {
    try {
        DefaultHttpClient Client = new DefaultHttpClient();
        Client.getCredentialsProvider().setCredentials(
                AuthScope.ANY,
                new UsernamePasswordCredentials("user", "passwd")
        );

        HttpGet httpGet = new HttpGet("https://httpbin.org/basic-auth/user/passwd");
        HttpResponse response = Client.execute(httpGet);

        System.out.println("response = " + response);

        BufferedReader breader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
        StringBuilder responseString = new StringBuilder();
        String line = "";
        while ((line = breader.readLine()) != null) {
            responseString.append(line);
        }
        breader.close();
        String responseStr = responseString.toString();
        System.out.println("responseStr = " + responseStr);

    } catch (IOException e) {
        e.printStackTrace();
    }
}

Base64.encodeBase64String ( "उपयोगकर्ता: पासवर्ड" .getBytes ()); मेरे लिए काम किया। DatatypeConverter.printBase64Binary () ने भी मेरे लिए काम किया। यह हो सकता है कि आपने पहले के मामले में मैसेज बॉडी में गलती की हो और यह एक खराब अनुरोध था। या शायद यह सर्वर पर निर्भर करता है।
किराए

5

हेडर सरणी का उपयोग करते समय

String auth = Base64.getEncoder().encodeToString(("test1:test1").getBytes());
Header[] headers = {
    new BasicHeader(HTTP.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString()),
    new BasicHeader("Authorization", "Basic " +auth)
};

3

HttpClient के लिए हमेशा उदाहरण के लिए HttpRequestInterceptor का उपयोग करें

httclient.addRequestInterceptor(new HttpRequestInterceptor() {
    public void process(HttpRequest arg0, HttpContext context) throws HttpException, IOException {
        AuthState state = (AuthState) context.getAttribute(ClientContext.TARGET_AUTH_STATE);
        if (state.getAuthScheme() == null) {
            BasicScheme scheme = new BasicScheme();
            CredentialsProvider credentialsProvider = (CredentialsProvider) context.getAttribute(ClientContext.CREDS_PROVIDER);
            Credentials credentials = credentialsProvider.getCredentials(AuthScope.ANY);
            if (credentials == null) {
                System.out.println("Credential >>" + credentials);
                throw new HttpException();
            }
            state.setAuthScope(AuthScope.ANY);
            state.setAuthScheme(scheme);
            state.setCredentials(credentials);
        }
    }
}, 0);

3

HttpBasicAuth मेरे लिए छोटे बदलावों के साथ काम करता है

  1. मैं मावेन निर्भरता का उपयोग करता हूं

    <dependency>
        <groupId>net.iharder</groupId>
        <artifactId>base64</artifactId>
        <version>2.3.8</version>
    </dependency>
  2. छोटा सा बदलाव

    String encoding = Base64.encodeBytes ((user + ":" + passwd).getBytes());

1

किसी भी Base64 विशिष्ट कॉल के बिना HTTP POST के साथ लॉगिन करने का एक आसान तरीका HTTPClient BasicCredentialsProvider का उपयोग करना है।

import java.io.IOException;
import static java.lang.System.out;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.HttpClientBuilder;

//code
CredentialsProvider provider = new BasicCredentialsProvider();
UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(user, password);
provider.setCredentials(AuthScope.ANY, credentials);
HttpClient client = HttpClientBuilder.create().setDefaultCredentialsProvider(provider).build();

HttpResponse response = client.execute(new HttpPost("http://address/test/login"));//Replace HttpPost with HttpGet if you need to perform a GET to login
int statusCode = response.getStatusLine().getStatusCode();
out.println("Response Code :"+ statusCode);

यह मेरे लिए काम नहीं कर रहा है। कॉल काम करता है लेकिन कोई प्रमाणीकरण हेडर मौजूद नहीं है।
लुकास84

अजीब है, क्या आपका प्रदाता ठीक से सेट है?
rjdkolb

अपने लाइब्रेरी के संस्करण को भी अपडेट करने का प्रयास करें। इसने मेरे लिए काम किया
rjdkolb
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.