Java 使用HttpUrlConnection进行抢占式基本身份验证?

Java 使用HttpUrlConnection进行抢占式基本身份验证?,java,android,http,authentication,basic-authentication,Java,Android,Http,Authentication,Basic Authentication,使用HttpUrlConnection使用抢占式基本http身份验证的最佳方法是什么。(假设现在我不能使用HttpClient) 编辑澄清:我正在使用Base64编码在请求头中正确设置un/pw。是否需要设置任何其他标志或属性,或者我正在为请求设置基本身份验证头这一事实是否是抢占式基本身份验证所需的全部内容?如果您使用的是Java 8或更高版本,Java.util.Base64可用: HttpURLConnection connection = (HttpURLConnection) new U

使用HttpUrlConnection使用抢占式基本http身份验证的最佳方法是什么。(假设现在我不能使用HttpClient)


编辑澄清:我正在使用Base64编码在请求头中正确设置un/pw。是否需要设置任何其他标志或属性,或者我正在为请求设置基本身份验证头这一事实是否是抢占式基本身份验证所需的全部内容?

如果您使用的是Java 8或更高版本,
Java.util.Base64
可用:

HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
String encoded = Base64.getEncoder().encodeToString((username+":"+password).getBytes(StandardCharsets.UTF_8));  //Java 8
connection.setRequestProperty("Authorization", "Basic "+encoded);

然后正常使用连接

如果您使用的是Java 7或更低版本,则需要一种将字符串编码为Base64的方法,例如:

byte[] message = (username+":"+password).getBytes("UTF-8");
String encoded = javax.xml.bind.DatatypeConverter.printBase64Binary(message);

是的,这就是使用基本身份验证所需做的全部工作。上面用于设置请求属性的代码应该在打开连接后以及获取输入或输出流之前立即执行。

顺便说一句,如果您使用
org.apache.commons.codec.binary.Base64
和do
Base64.encodeBase64String()也会出现android问题,以防其他人遇到同样的问题
。您需要执行
Base64.encodeBase64()
并获取字节[],然后构造字符串


这让我措手不及,因为这两种方法之间的行尾结果会有所不同。

关于Base64编码问题,我发现了以下库:

我还没有完全检查过它,但我将它用于上面所示的基本身份验证解决方案(以及图像编码/解码),并且它工作得很好。它为是否包含换行符提供了一个参数。

您可以使用它来配置基本身份验证。对于应用程序发送的每个请求,请参阅:


    • 我也有这个问题。 现在我已经解决了这个问题。 我的代码是:

          URL url = new URL(stringUrl);
      
          String authStr = "MyAPIKey"+":"+"Password";
          System.out.println("Original String is " + authStr);
      
       // encode data on your side using BASE64
          byte[] bytesEncoded = Base64.encodeBase64(authStr .getBytes());
          String authEncoded = new String(bytesEncoded);
      
          HttpURLConnection connection = (HttpURLConnection) url.openConnection();
          connection.setRequestProperty("Authorization", "Basic "+authEncoded);
      
      它可能会帮助许多其他人。
      祝你好运。

      你需要做的就是复制粘贴它,祝你快乐

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

      是的,这就是你要做的。很酷,谢谢。原来我的问题在别处。我知道HttpClient有一个setPreemptiveAuth类型的接口,我想知道HttpUrlConnection是否也有类似的接口。对于使用android.util.Base64进行编码的任何人来说,只是一个小小的警告,默认标志将附加一个换行符,从而为您创建无效的HTTP请求,导致您浪费数小时的时间试图弄清楚为什么像nginx这样的HTTP服务器会为您的请求报告htp400错误代码!因此,请确保使用“无包裹”标志!上面的代码对我不起作用。这是有效的:
      stringencoded=Base64.encodeToString((username+“:”+password).getBytes(“UTF-8”),Base64.NO_-WRAP);connection.setRequestProperty(“授权”、“基本”+编码)
      注意,我没有成功地使用
      Base64.encode
      only(即不使用'encodeToString'),因为它产生了一些奇怪的结果字节,其ASCII表示形式甚至与Base64不相似。请注意java.util.Base64版本的用户:
      String encoded=Base64.getEncoder().withoutPadding().encodeToString((用户名+“:“+密码).getBytes(标准字符集.UTF_8))(.withoutPadding()删除结尾处的额外换行。)