Java azure rest api文件创建。验证请求失败。格式正确,包括签名。响应代码:403此错误
我相信您出现此错误的原因是因为您在请求头中使用Java azure rest api文件创建。验证请求失败。格式正确,包括签名。响应代码:403此错误,java,azure,rest,api,Java,Azure,Rest,Api,我相信您出现此错误的原因是因为您在请求头中使用application/octet stream值指定Content-Type,而不是在stringToSign中。请将您的stringToSign更改为类似以下内容: import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.text.Simp
application/octet stream
值指定Content-Type
,而不是在stringToSign
中。请将您的stringToSign
更改为类似以下内容:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.TimeZone;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import com.microsoft.azure.storage.core.Base64;
public class TestCloudStorage {
private static final String account = "account-name";
private static final String key = "key";
public static void main(String args[]) throws Exception {
createFile();
}
public static void createFile() throws Exception {
System.setProperty("sun.net.http.allowRestrictedHeaders", "true");
String urlString = "https://" + account + ".file.core.windows.net/myfileshare/mydirectory/myfile";
System.setProperty("https.proxyHost", "proxy");
System.setProperty("https.proxyPort", "8080");
HttpURLConnection connection = (HttpURLConnection)(new URL(urlString)).openConnection();
getFileRq(connection, account, key);
connection.connect();
System.out.println("Response message : " + connection.getResponseMessage());
System.out.println("Response code : " + connection.getResponseCode());
BufferedReader br = null;
if (connection.getResponseCode() != 200 && connection.getResponseCode() != 201) {
br = new BufferedReader(new InputStreamReader((connection.getErrorStream())));
}
else {
br = new BufferedReader(new InputStreamReader((connection.getInputStream())));
}
System.out.println("Response body : " + br.readLine());
}
public static void getFileRq(HttpURLConnection request, String account, String key) throws Exception {
SimpleDateFormat fmt = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss");
fmt.setTimeZone(TimeZone.getTimeZone("GMT"));
String date = fmt.format(Calendar.getInstance().getTime()) + " GMT";
String stringToSign = "PUT" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\nx-ms-content-length:1024" + "\nx-ms-date:" + date + "\nx-ms-type:file" + "\nx-ms-version:" + "2015-02-21" + +"/" + account + request.getURL().getPath();
System.out.println("stringToSign : " + stringToSign);
String auth = getAuthenticationString(stringToSign);
System.out.println(auth);
request.setRequestMethod("PUT");
request.setRequestProperty("x-ms-version", "2015-02-21");
request.setRequestProperty("x-ms-date", date);
request.setRequestProperty("Content-Type", "application/octet-stream");
request.setRequestProperty("x-ms-content-length", "1024");
request.setRequestProperty("Authorization", auth);
request.setRequestProperty("x-ms-type", "file");
request.setRequestProperty("Content-Length", "0");
}
private static String getAuthenticationString(String stringToSign) throws Exception {
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(Base64.decode(key), "HmacSHA256"));
String authKey = new String(Base64.encode(mac.doFinal(stringToSign.getBytes("UTF-8"))));
String auth = "SharedKey " + account + ":" + authKey;
return auth;
}
}
或者您可以从请求头中删除内容类型
,因为默认情况下,内容类型为应用程序/octet流
更新
我还注意到2015-02-21
(x-ms-version的值)之后缺少一个新行字符。你能补充一下吗
String stringToSign = "PUT" + "\n" + "\n" + "\n" + "\n" + "\n" + "application/octet-stream\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\nx-ms-content-length:1024" + "\nx-ms-date:" + date + "\nx-ms-type:file" + "\nx-ms-version:" + "2015-02-21" + +"/" + account + request.getURL().getPath();
请花点时间格式化有问题的代码,使其至少可读。我试图格式化代码,但无法在堆栈溢出时格式化代码。@RahiMuzammil我已经为您完成了!下一次,请尝试将格式化代码作为不可读代码发布,这对于社区成员来说非常难阅读和解决。请看这里,为了您的耐心和花时间格式化代码,您可以如何@MdFaridUddinKiron BIG+1@为了社区的利益,GauravMantri有时需要耐心。我帮助新会员。谢谢你的灵感。请编辑你的问题并加入你上次尝试的代码。另外,请打印
stringToSign
的输出。还有一件事:当您收到错误时,将错误响应流读取为字符串。这将有更详细的错误消息。请在你的问题中也包括这一点。但我已经做了修改。你在说什么?您应该能够编辑您的问题。只需点击问题下方的“编辑”链接,用最新代码更新问题,然后保存编辑。
String stringToSign = "PUT" + "\n" + "\n" + "\n" + "\n" + "\n" + "application/octet-stream\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\nx-ms-content-length:1024" + "\nx-ms-date:" + date + "\nx-ms-type:file" + "\nx-ms-version:" + "2015-02-21" + "\n/" + account + request.getURL().getPath();