दूरस्थ URL से कनेक्ट करना जिसमें जावा का उपयोग करके प्रमाणीकरण की आवश्यकता होती है


125

मैं जावा में एक दूरस्थ URL से कैसे जुड़ूं जिसे प्रमाणीकरण की आवश्यकता है। मैं निम्नलिखित कोड को संशोधित करने के लिए एक तरीका खोजने की कोशिश कर रहा हूं जो कि प्रोग्रामर / पासवर्ड प्रदान करने में सक्षम हो ताकि यह 401 को फेंक न सके।

URL url = new URL(String.format("http://%s/manager/list", _host + ":8080"));
HttpURLConnection connection = (HttpURLConnection)url.openConnection();

जवाबों:


134

आप इस तरह से http अनुरोधों के लिए डिफ़ॉल्ट प्रमाणक सेट कर सकते हैं:

Authenticator.setDefault (new Authenticator() {
    protected PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication ("username", "password".toCharArray());
    }
});

इसके अलावा, यदि आपको अधिक लचीलेपन की आवश्यकता है, तो आप Apache HttpClient की जांच कर सकते हैं , जो आपको अधिक प्रमाणीकरण विकल्प देगा (साथ ही सत्र समर्थन, आदि)


4
आप एक खराब प्रमाणीकरण घटना को कैसे संभालते हैं? [उदाहरण के लिए, यदि उपयोगकर्ता उपयोगकर्ता नाम और पासवर्ड प्रमाणीकरण क्रेडेंशियल्स की आपूर्ति करता है जो कुछ भी मेल नहीं खाता है]?
SK9

2
उपरोक्त कोड काम करता है, लेकिन व्हाट्सएप के रूप में काफी निहित है। अगर वहाँ क्या हो रहा है, यह जानने के लिए आप उन कक्षाओं के लिए डॉक्स में खुदाई कर रहे हैं, वहां उप-क्लासिंग और विधि ओवरराइडिंग हो रही है। यहाँ कोड अधिक स्पष्ट javacodegeeks
Fuchida

12
क्या विश्व स्तर पर इसे स्थापित करने के बजाय विशिष्ट Authenticatorप्रति URL.openConnection()आह्वान को निर्धारित करना संभव है ?
यूरी नकोनचैनी

@ यूरा: नहीं। यह वैश्विक हो गया है। हालाँकि, आप वैश्विक प्रमाणक सेट करने जैसी बुरी चीजें कर सकते हैं जो क्रेडेंशियल्स को थ्रेड-लोकल वैरिएबल से बाहर निकालता है, और HTTP कनेक्शन बनाने से पहले क्रेडेंशियल्स प्रति थ्रेड सेट करता है।
डेविड

4
@YuriyNakonechnyy के जवाब में ... यदि आप जावा 9 या उससे ऊपर का उपयोग कर रहे हैं तो आप कॉल कर सकते हैं HttpURLConnection.setAuthenticator()। दुर्भाग्य से जावा 8 और उससे पहले का, प्रामाणिक उदाहरण जेवीएम-वाइड-ग्लोबल वैरिएबल है। देखें: docs.oracle.com/javase/9/docs/api/java/net/…
नील बार्टलेट

133

एक देशी और कम घुसपैठ विकल्प है, जो केवल आपके कॉल के लिए काम करता है।

URL url = new URL(“location address”);
URLConnection uc = url.openConnection();
String userpass = username + ":" + password;
String basicAuth = "Basic " + new String(Base64.getEncoder().encode(userpass.getBytes()));
uc.setRequestProperty ("Authorization", basicAuth);
InputStream in = uc.getInputStream();

5
Base64 क्लास को Apache Commons Codec द्वारा प्रदान किया जा सकता है।
मैथ्यू बकेट

मेरे लिए इस तरह से काम नहीं किया ... केवल तरीका है कि @James Van Huis अच्छा था
मिगेल रिबेरो

यह ग्रेल्स और कई अन्य जावा फ्रेमवर्क पर 'देशी' है क्योंकि ये सभी अपाचे कॉमन्स लिब का उपयोग करते हैं।
वांडरसन सैंटोस

1
सामान्य रूप से तब तक काम नहीं करता है जब तक आप .trim()परिणाम नहीं देते हैं, या एक विधि संस्करण को कॉल नहीं करते हैं जो कि चक्क्ड आउटपुट का उत्पादन नहीं करता है। javax.xml.bind.DatatypeConverterअधिक सुरक्षित लगता है।
जेसी ग्लेक

मैंने इस उत्तर में आपका कोड उद्धृत किया है धन्यवाद
नोट्स-जेज

77

आप निम्न का भी उपयोग कर सकते हैं, जिसमें बाहरी पैकेज का उपयोग करने की आवश्यकता नहीं है:

URL url = new URL(“location address”);
URLConnection uc = url.openConnection();

String userpass = username + ":" + password;
String basicAuth = "Basic " + javax.xml.bind.DatatypeConverter.printBase64Binary(userpass.getBytes());

uc.setRequestProperty ("Authorization", basicAuth);
InputStream in = uc.getInputStream();

10
मैं इतने लंबे समय के लिए जावा मानक संकुल के अंदर एक Base64 एनकोडर की तलाश में था! धन्यवाद
qwertzguy

ध्यान दें कि Java9 + के लिए आपको शायद इसलिए करना होगा --add-modules javax.xml.bindक्योंकि उन्होंने पैकेज को डिफ़ॉल्ट क्लासपाथ से हटा दिया था। और Java11 + में इसे पूरी तरह से हटा दिया गया है, आपको फिर से एक बाहरी निर्भरता की आवश्यकता है। ऐसी है प्रगति!
एड रान्डेल

1
@EdRandall java.util.Base64अब एक है इसलिए यह वास्तव में प्रगति है :)
स्टीवन श्लांसकर

42

यदि आप प्रोटोकॉल और डोमेन के बीच उपयोगकर्ता नाम और पासवर्ड दर्ज करते हुए सामान्य लॉगिन का उपयोग कर रहे हैं तो यह सरल है। यह लॉगिन के साथ और बिना भी काम करता है।

नमूना यूआरएल: http: // उपयोगकर्ता: pass@domain.com/url

URL url = new URL("http://user:pass@domain.com/url");
URLConnection urlConnection = url.openConnection();

if (url.getUserInfo() != null) {
    String basicAuth = "Basic " + new String(new Base64().encode(url.getUserInfo().getBytes()));
    urlConnection.setRequestProperty("Authorization", basicAuth);
}

InputStream inputStream = urlConnection.getInputStream();

कृपया टिप्पणी में ध्यान दें, नीचे वैलेरीबोडक से, यह एंड्रॉइड विकास वातावरण में कैसे किया जाता है।


1
यह वही है जो मैं पिछले 30 मिनट से खोज रहा था । आपका बहुत बहुत धन्यवाद!
गीर्ट श्योरिंग

यदि आपके उपयोगकर्ता नाम / पासवर्ड में विशेष वर्ण हैं, तो मेरा मानना ​​है कि आपको उन लोगों को urlencode करने की आवश्यकता होगी। फिर, ऊपर कोड का स्निपेट में, आप से होकर गुजरेगा url.getUserInfo()thorugh URLDecoder.decode()पहले (@Peter Rader)।
m01

धन्यवाद, लेकिन Android के लिए आपको निम्नलिखित के रूप में बेस 64 का उपयोग करना चाहिए: स्ट्रिंग बेसिकऑथ = "बेसिक" + Base64.encodeToString (url.getUserInfo ()। GetBytes (), Base64.DEFAULT); httpConn.setRequestProperty ("प्राधिकरण", basicAuth);
वल्लरीबोडक

उस पूरक के लिए धन्यवाद valerybodak!
javabeangrinder

8

जैसा कि मैं एक Android- Java- उत्तर की तलाश में यहां आया हूं, मैं एक संक्षिप्त सारांश करने जा रहा हूं:

  1. जेम्स वैन Huis द्वारा दिखाए अनुसार java.net.Authenticator का उपयोग करें
  2. इस उत्तर में अपाचे कॉमन्स HTTP क्लाइंट का उपयोग करें
  3. मूल java.net.URLConnection का उपयोग करें और प्रमाणीकरण-हैडर को मैन्युअल रूप से यहां दिखाए गए अनुसार सेट करें

यदि आप java.net.URLConnection का बेसिक ऑथेंटिकेशन के साथ उपयोग करना चाहते हैं एंड्रॉयड के लिए इस कोड का प्रयास करें:

URL url = new URL("http://www.mywebsite.com/resource");
URLConnection urlConnection = url.openConnection();
String header = "Basic " + new String(android.util.Base64.encode("user:pass".getBytes(), android.util.Base64.NO_WRAP));
urlConnection.addRequestProperty("Authorization", header);
// go on setting more request headers, reading the response, etc

1
धन्यवाद। एक Android विशिष्ट उत्तर की तलाश में था!
स्टीफन मैककॉर्मिक

5

HttpsURLConnection का उपयोग करके ऑर्ट को सेट करने में सक्षम था

           URL myUrl = new URL(httpsURL);
            HttpsURLConnection conn = (HttpsURLConnection)myUrl.openConnection();
            String userpass = username + ":" + password;
            String basicAuth = "Basic " + new String(Base64.getEncoder().encode(userpass.getBytes()));
            //httpsurlconnection
            conn.setRequestProperty("Authorization", basicAuth);

इस पोस्ट से कुछ परिवर्तन आए। और Base64 java.util पैकेज से है।


3

"बेस 64 ()। एनकोड ()" दृष्टिकोण के साथ वास्तव में सावधान रहें, मेरी टीम और मुझे 400 अपाचे खराब अनुरोध मुद्दे मिल गए क्योंकि यह स्ट्रिंग के अंत में एक \ r \ n जोड़ता है।

हमने इसे विंडसर्क की बदौलत पैकेट सूँघते पाया।

यहाँ हमारे समाधान है:

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

HttpGet getRequest = new HttpGet(endpoint);
getRequest.addHeader("Authorization", "Basic " + getBasicAuthenticationEncoding());

private String getBasicAuthenticationEncoding() {

        String userPassword = username + ":" + password;
        return new String(Base64.encodeBase64(userPassword.getBytes()));
    }

आशा करता हूँ की ये काम करेगा!


3

मूल प्रमाणीकरण के लिए इस कोड का उपयोग करें।

URL url = new URL(path);
String userPass = "username:password";
String basicAuth = "Basic " + Base64.encodeToString(userPass.getBytes(), Base64.DEFAULT);//or
//String basicAuth = "Basic " + new String(Base64.encode(userPass.getBytes(), Base64.No_WRAP));
HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
urlConnection.setRequestProperty("Authorization", basicAuth);
urlConnection.connect();


2

मैं इस मामले के लिए एक उत्तर देना चाहता हूं कि आपके पास कनेक्शन खोलने वाले कोड पर नियंत्रण नहीं है। जैसे मैंने प्रयोग करते समय किया थाURLClassLoader पासवर्ड प्रोटेक्टेड सर्वर से जार फाइल लोड करने लिए ।

Authenticatorसमाधान काम करते हैं लेकिन दोष यह है कि यह पहली बार एक पासवर्ड के बिना और केवल एक पासवर्ड के लिए एक प्रदान करता है सर्वर पूछता है के बाद सर्वर तक पहुँचने के लिए कोशिश करता है है जाएगा। यह एक अनावश्यक राउंडट्रिप है अगर आपको पहले से ही पता है कि सर्वर को पासवर्ड की आवश्यकता होगी।

public class MyStreamHandlerFactory implements URLStreamHandlerFactory {

    private final ServerInfo serverInfo;

    public MyStreamHandlerFactory(ServerInfo serverInfo) {
        this.serverInfo = serverInfo;
    }

    @Override
    public URLStreamHandler createURLStreamHandler(String protocol) {
        switch (protocol) {
            case "my":
                return new MyStreamHandler(serverInfo);
            default:
                return null;
        }
    }

}

public class MyStreamHandler extends URLStreamHandler {

    private final String encodedCredentials;

    public MyStreamHandler(ServerInfo serverInfo) {
        String strCredentials = serverInfo.getUsername() + ":" + serverInfo.getPassword();
        this.encodedCredentials = Base64.getEncoder().encodeToString(strCredentials.getBytes());
    }

    @Override
    protected URLConnection openConnection(URL url) throws IOException {
        String authority = url.getAuthority();
        String protocol = "http";
        URL directUrl = new URL(protocol, url.getHost(), url.getPort(), url.getFile());

        HttpURLConnection connection = (HttpURLConnection) directUrl.openConnection();
        connection.setRequestProperty("Authorization", "Basic " + encodedCredentials);

        return connection;
    }

}

यह एक नया प्रोटोकॉल पंजीकृत myकरता है जिसे httpक्रेडेंशियल्स जोड़ने पर प्रतिस्थापित किया जाता है। तो जब नया बनाने के साथ URLClassLoaderबस की जगह और सब कुछ ठीक है। मुझे पता है कि एक कंस्ट्रक्टर प्रदान करता है, लेकिन यह कारखाना उपयोग नहीं किया जाता है यदि URL एक जार फ़ाइल को इंगित करता है।httpmyURLClassLoaderURLStreamHandlerFactory


1

जावा 9 के बाद से, आप यह कर सकते हैं

URL url = new URL("http://www.example.com");
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
connection.setAuthenticator(new Authenticator() {
    protected PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication ("USER", "PASS".toCharArray());
    }
});

2
setAuthenticator()विधि नहीं देखी ।
पश्चिमीगंज

0

ANDROD इम्प्लिमेंटेशन वेब सेवा से डेटा / स्ट्रिंग प्रतिक्रिया का अनुरोध करने का एक पूरा तरीका उपयोगकर्ता नाम और पासवर्ड के साथ प्राधिकरण का अनुरोध करता है

public static String getData(String uri, String userName, String userPassword) {
        BufferedReader reader = null;
        byte[] loginBytes = (userName + ":" + userPassword).getBytes();

        StringBuilder loginBuilder = new StringBuilder()
                .append("Basic ")
                .append(Base64.encodeToString(loginBytes, Base64.DEFAULT));

        try {
            URL url = new URL(uri);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.addRequestProperty("Authorization", loginBuilder.toString());

            StringBuilder sb = new StringBuilder();
            reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            String line;
            while ((line = reader.readLine())!= null){
                sb.append(line);
                sb.append("\n");
            }

            return  sb.toString();

        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            if (null != reader){
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

0

मैंने यह किया है कि आपको यह करने की ज़रूरत है कि कॉपी पेस्ट करें यह खुश हो

    HttpURLConnection urlConnection;
    String url;
 //   String data = json;
    String result = null;
    try {
        String username ="danish.hussain@gmail.com";
        String password = "12345678";

        String auth =new String(username + ":" + password);
        byte[] data1 = auth.getBytes(UTF_8);
        String base64 = Base64.encodeToString(data1, Base64.NO_WRAP);
        //Connect
        urlConnection = (HttpURLConnection) ((new URL(urlBasePath).openConnection()));
        urlConnection.setDoOutput(true);
        urlConnection.setRequestProperty("Content-Type", "application/json");
        urlConnection.setRequestProperty("Authorization", "Basic "+base64);
        urlConnection.setRequestProperty("Accept", "application/json");
        urlConnection.setRequestMethod("POST");
        urlConnection.setConnectTimeout(10000);
        urlConnection.connect();
        JSONObject obj = new JSONObject();

        obj.put("MobileNumber", "+97333746934");
        obj.put("EmailAddress", "danish.hussain@mee.com");
        obj.put("FirstName", "Danish");
        obj.put("LastName", "Hussain");
        obj.put("Country", "BH");
        obj.put("Language", "EN");
        String data = obj.toString();
        //Write
        OutputStream outputStream = urlConnection.getOutputStream();
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
        writer.write(data);
        writer.close();
        outputStream.close();
        int responseCode=urlConnection.getResponseCode();
        if (responseCode == HttpsURLConnection.HTTP_OK) {
            //Read
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), "UTF-8"));

        String line = null;
        StringBuilder sb = new StringBuilder();

        while ((line = bufferedReader.readLine()) != null) {
            sb.append(line);
        }

        bufferedReader.close();
        result = sb.toString();

        }else {
        //    return new String("false : "+responseCode);
        new String("false : "+responseCode);
        }

    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (JSONException e) {
        e.printStackTrace();
    }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.