首页 > 解决方案 > 基本 httpurlconnection POST 请求失败,出现 401

问题描述

我已经尝试了多种方法来纠正这个问题,但不确定问题是什么。对于 POST 请求,我尝试在 Base64 中对用户名凭据进行编码,并将其设置为 requestProperty 值。还尝试将其作为参数添加到 POST 正文,但在这两种情况下,请求都失败并出现 401 错误。显然,尽管在 POSTMAN 请求中使用它时,凭据没有被识别,但它工作正常。然后,我使用 BASIC auth 值复制了该请求中使用的标头,并且仍然是相同的错误代码。也许我没有清楚地看到这个问题:

    obj = new URL(urlRequest);
    conn = (HttpsURLConnection) obj.openConnection();
    conn.setRequestMethod("POST");
    conn.setRequestProperty("User-Agent", "PostmanRuntime/7.28.3");
    conn.setRequestProperty("Accept", "*/*");
    conn.setRequestProperty("Connection", "keep-alive");
    conn.setRequestProperty("Content-Type","multipart/form-data");
    //String userCredentials = "_username=xxxxxxxx&_password=yyyyyyyy";
    //String basicAuth = "Basic " + new 
      String(Base64.getEncoder().encode(userCredentials.getBytes()));
    //conn.setRequestProperty("Authorization", basicAuth);
    conn.setRequestProperty("_username", "xxxxxxxxxx");
    conn.setRequestProperty("_password", "yyyyyyyyyy");
    
    List<NameValuePair> params = new ArrayList<NameValuePair>();
    params.add(new BasicNameValuePair("_username", "xxxxxxxxxx"));
    params.add(new BasicNameValuePair("_password", "yyyyyyyyyy"));
    String urlParameters = "_username=xxxxxxxxxx&_password=yyyyyyyyyy";
    
    conn.setDoOutput(true);
    try (DataOutputStream wr = new DataOutputStream(conn.getOutputStream())) {
            wr.writeBytes(urlParameters);
            wr.flush();
    }

    InputStream urlInputStream; 
    int errCode = conn.getResponseCode();
    BufferedReader inSt = new BufferedReader(new InputStreamReader(conn.getInputStream(), 
      "UTF-8"));
    StringBuilder response = new StringBuilder();

标签: javaposthttpurlconnection

解决方案


HTTP 基本身份验证

在 HTTP 基本身份验证方案中,Base64 编码凭据采用username:password. 尝试这个:

String username = "xxxxxxxxxx", password = "yyyyyyyyyy";
conn.setRequestProperty("Authorization", "Basic " +
  Base64.getEncoder().encodeToString(
    (username + ":" + password).getBytes()));

RFC2617:HTTP 身份验证:基本和摘要访问身份验证

为了接收授权,客户端在凭证中的 base64 编码字符串中发送用户 ID 和密码,由单个冒号 (":") 字符分隔。

(附带说明:用户名中不能有冒号。)

内容类型

如果内容不是多部分格式Content-Type则应相应更改标题。如果是内容格式,请key1=value1&key2=value2&...尝试以下操作:

conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

有关更多信息,请参阅此答案


推荐阅读