创建Azure Rest API文件。无法验证请求。格式正确,包括签名。响应码:403此错误

时间:2019-05-30 07:07:54

标签: java azure rest api

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

1 个答案:

答案 0 :(得分:0)

我相信您收到此错误的原因是因为您在请求标头中指定了Content-Type值为application/octet-stream,而不是在stringToSign中指定了值。请将您的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" + +"/" + account + request.getURL().getPath();

或者您可以从请求标头中删除Content-Type,因为默认情况下,内容类型为application/octet-stream

更新

我还注意到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" + "\n/" + account + request.getURL().getPath();