2009-01-30 37 views
98

如何連接到需要認證的Java遠程URL。我試圖找到一種方法來修改下面的代碼,以便能夠以編程方式提供用戶名/密碼,所以它不會拋出401連接到需要使用Java進行認證的遠程URL

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

回答

112

您可以設置這樣的HTTP請求的默認認證:

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

另外,如果你需要更多的靈活性,你可以檢查出Apache HttpClient,這將給你更多的身份驗證選項(以及會話支持,等等)

+3

如何處理錯誤的身份驗證事件? [例如,如果用戶提供不匹配任何內容的用戶名和密碼認證憑證]? – SK9 2011-08-14 06:06:01

+3

這個答案拯救了我的一天! – 2013-09-20 17:05:09

+2

上面的代碼工作正常,但對於發生了什麼卻很隱含。 有子類和方法重寫在那裏,如果你想知道發生了什麼,深入這些類的文檔。 這裏的代碼更明確[javacodegeeks](http://examples.javacodegeeks.com/core-java/net/authenticator/access-password-protected-url-with-authenticator/) – Fuchida 2014-05-07 17:01:31

91

有一個本地以及低侵入替代方案,它只適用於y我們的電話。

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

您也可以使用下面的,它不需要使用外部包:

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(); 
31

如果您使用的是正常登錄,而進入協議,這是該域的用戶名和密碼簡單。它也適用於和不用登錄。

樣品網址:http://user:[email protected]/url

URL url = new URL("http://user:[email protected]/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(); 
3

非常小心的 「Base64編碼()編碼()」 的方法,我的團隊和我有400分Apache的錯誤的請求的問題,因爲它增加了在\ r \ n生成的字符串結束。

感謝Wireshark,我們發現它嗅探數據包。

這裏是我們的解決方案:

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

希望它能幫助!

8

因爲我已經來到這裏尋找一個Android的Java的答案,我會怎麼做一個簡短的總結:

  1. 使用java.net.Authenticator中如圖James van Huis
  2. 使用阿帕奇共享HTTP客戶端,如在this Answer
  3. 使用基本java.net.URLConnection中並手動設置認證報頭狀所示here

如果要使用java.net。URLConnection的使用基本身份驗證在的Android試試這個代碼:

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 
0

ANDROD實現 一個完整的方法來請求從Web服務數據/串響應,要求輸入用戶名和密碼

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

授權使用此代碼進行基本認證。

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

1

我想爲你沒有在打開的連接的代碼控制的情況下的答案。我使用URLClassLoader從受密碼保護的服務器加載jar文件時所做的鏈接。

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; 
    } 

} 

這將註冊一個新的協議myhttp替換被添加憑證時。所以當創建新的URLClassLoader只需用my替換http,一切都很好。我知道URLClassLoader提供了一個構造函數,它需要一個URLStreamHandlerFactory,但如果URL指向一個jar文件,則不會使用此工廠。

相關問題