[英]Cannot access azure blobs through rest api
I was able to create a Container in Storage Account and upload a blob to it through the Client Side Code. 我能够在存储帐户中创建一个容器,然后通过客户端代码将一个Blob上载到该容器。
I was able to make the blob available for Public access as well , such that when I hit the following query from my browser, I am able to see the image which I uploaded. 我也可以使该Blob可供“公共访问”使用,这样,当我从浏览器中命中以下查询时,便可以看到上传的图像。
https://MYACCOUNT.blob.core.windows.net/MYCONTAINER/MYBLOB
I now have a requirement to use the rest service to retrieve the contents of the blob. 现在,我需要使用rest服务来检索blob的内容。 I wrote down the following java code.
我写下了以下Java代码。
package main;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
public class GetBlob {
public static void main(String[] args) {
String url="https://MYACCOUNT.blob.core.windows.net/MYCONTAINER/MYBLOB";
try {
System.out.println("RUNNIGN");
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
connection.setRequestProperty("Authorization", createQuery());
connection.setRequestProperty("x-ms-version", "2009-09-19");
InputStream response = connection.getInputStream();
System.out.println("SUCCESSS");
String line;
BufferedReader reader = new BufferedReader(new InputStreamReader(response));
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static String createQuery()
{
String dateFormat="EEE, dd MMM yyyy hh:mm:ss zzz";
SimpleDateFormat dateFormatGmt = new SimpleDateFormat(dateFormat);
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("UTC"));
String date=dateFormatGmt.format(new Date());
String Signature="GET\n\n\n\n\n\n\n\n\n\n\n\n" +
"x-ms-date:" +date+
"\nx-ms-version:2009-09-19" ;
// I do not know CANOCALIZED RESOURCE
//WHAT ARE THEY??
// +"\n/myaccount/myaccount/mycontainer\ncomp:metadata\nrestype:container\ntimeout:20";
String SharedKey="SharedKey";
String AccountName="MYACCOUNT";
String encryptedSignature=(encrypt(Signature));
String auth=""+SharedKey+" "+AccountName+":"+encryptedSignature;
return auth;
}
public static String encrypt(String clearTextPassword) {
try {
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(clearTextPassword.getBytes());
return new sun.misc.BASE64Encoder().encode(md.digest());
} catch (NoSuchAlgorithmException e) {
}
return "";
}
}
However , I get the following error when I run this main class... 但是,运行此主类时出现以下错误...
RUNNIGN
java.io.IOException: Server returned HTTP response code: 403 for URL: https://klabs.blob.core.windows.net/delete/Blob_1
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(Unknown Source)
at main.MainClass.main(MainClass.java:61)
Question1: Why this error, did I miss any header/parameter? 问题1:为什么会出现此错误,我是否错过任何标题/参数?
Question2: Do I need to add headers in the first place, because I am able to hit the request from the browser without any issues. Question2:我是否需要首先添加标题,因为我能够从浏览器中访问请求而没有任何问题。
Question3: Can it be an SSL issue? 问题3:这可能是SSL问题吗? What is the concept of certificates, and how and where to add them?
证书的概念是什么,以及如何以及在何处添加证书? Do I really need them?
我真的需要它们吗? Will I need them later, when I do bigger operations on my blob storage(I want to manage a thousand blobs)?
当我在Blob存储上执行较大的操作(我想管理一千个Blob)时,以后是否需要它们?
Will be thankful for any reference as well, within Azure and otherwise that could help me understand better. 还要感谢Azure中的任何参考,否则可以帮助我更好地理解。 :D
:d
AFTER A FEW DAYS 几天后
Below is my new code for PutBlob I azure. 以下是天蓝色的PutBlob的新代码。 I believe I have fully resolved all header and parameter issues and my request is perfect.
我相信我已经完全解决了所有标头和参数问题,并且我的要求很完美。 However I am still getting the same 403. I do not know what the issue is.
但是我仍然收到相同的403。我不知道问题出在哪里。 Azure is proving to be pretty difficult.
事实证明,Azure很难。
A thing to note is that the containers name is delete, and I want to create a blob inside it, say newBlob. 需要注意的是容器名称是delete,我想在其中创建一个blob,例如newBlob。 I tried to initialize the urlPath in the code below with both "delete" and "delete/newBlob".
我试图在下面的代码中使用“ delete”和“ delete / newBlob”来初始化urlPath。 Does not work..
不起作用..
package main;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URISyntaxException;
import java.net.URL;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.TimeZone;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException;
import com.sun.org.apache.xml.internal.security.utils.Base64;
public class Internet {
static String key="password";
static String account="klabs";
private static Base64 base64 ;
private static String createAuthorizationHeader(String canonicalizedString) throws InvalidKeyException, Base64DecodingException, NoSuchAlgorithmException, IllegalStateException, UnsupportedEncodingException {
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(base64.decode(key), "HmacSHA256"));
String authKey = new String(base64.encode(mac.doFinal(canonicalizedString.getBytes("UTF-8"))));
String authStr = "SharedKey " + account + ":" + authKey;
return authStr;
}
public static void main(String[] args) {
System.out.println("INTERNET");
String key="password";
String account="klabs";
long blobLength="Dipanshu Verma wrote this".getBytes().length;
File f = new File("C:\\Users\\Dipanshu\\Desktop\\abc.txt");
String requestMethod = "PUT";
String urlPath = "delete";
String storageServiceVersion = "2009-09-19";
SimpleDateFormat fmt = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:sss");
fmt.setTimeZone(TimeZone.getTimeZone("UTC"));
String date = fmt.format(Calendar.getInstance().getTime()) + " UTC";
String blobType = "BlockBlob";
String canonicalizedHeaders = "x-ms-blob-type:"+blobType+"\nx-ms-date:"+date+"\nx-ms-version:"+storageServiceVersion;
String canonicalizedResource = "/"+account+"/"+urlPath;
String stringToSign = requestMethod+"\n\n\n"+blobLength+"\n\n\n\n\n\n\n\n\n"+canonicalizedHeaders+"\n"+canonicalizedResource;
try {
String authorizationHeader = createAuthorizationHeader(stringToSign);
URL myUrl = new URL("https://klabs.blob.core.windows.net/" + urlPath);
HttpURLConnection connection=(HttpURLConnection)myUrl.openConnection();
connection.setRequestProperty("x-ms-blob-type", blobType);
connection.setRequestProperty("Content-Length", String.valueOf(blobLength));
connection.setRequestProperty("x-ms-date", date);
connection.setRequestProperty("x-ms-version", storageServiceVersion);
connection.setRequestProperty("Authorization", authorizationHeader);
connection.setDoOutput(true);
connection.setRequestMethod("POST");
System.out.println(String.valueOf(blobLength));
System.out.println(date);
System.out.println(storageServiceVersion);
System.out.println(stringToSign);
System.out.println(authorizationHeader);
System.out.println(connection.getDoOutput());
DataOutputStream outStream = new DataOutputStream(connection.getOutputStream());
// Send request
outStream.writeBytes("Dipanshu Verma wrote this");
outStream.flush();
outStream.close();
DataInputStream inStream = new DataInputStream(connection.getInputStream());
System.out.println("BULLA");
String buffer;
while((buffer = inStream.readLine()) != null) {
System.out.println(buffer);
}
// Close I/O streams
inStream.close();
outStream.close();
} catch (InvalidKeyException | Base64DecodingException | NoSuchAlgorithmException | IllegalStateException | UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I know only a proper code reviewer might be able to help me, please do it if you can. 我知道只有适当的代码审阅者才能为我提供帮助,如果可以的话,请这样做。 Thanks
谢谢
Question1: Why this error, did I miss any header/parameter?
问题1:为什么会出现此错误,我是否错过任何标题/参数?
Most likely you're getting this error is because of incorrect signature. 您最有可能收到此错误是由于签名不正确。 Please refer to MSDN documentation for creating correct signature: http://msdn.microsoft.com/en-us/library/azure/dd179428.aspx .
请参考MSDN文档以创建正确的签名: http : //msdn.microsoft.com/zh-cn/library/azure/dd179428.aspx 。 Unless your signature is correct you'll not be able to perform operations using REST API.
除非您的签名正确,否则您将无法使用REST API执行操作。
Question2: Do I need to add headers in the first place, because I am able to hit the request from the browser without any issues.
Question2:我是否需要首先添加标题,因为我能够从浏览器中访问请求而没有任何问题。
In your current scenario, because you can access the blob directly (which in turn means the container in which the blob exist has Public
or Blob
ACL) you don't really need to use REST API. 在当前情况下,由于您可以直接访问Blob(这反过来意味着Blob存在的容器具有
Public
或Blob
ACL),因此您实际上不需要使用REST API。 You can simply make a HTTP request using Java and read the response stream which will have blob contents. 您可以简单地使用Java发出HTTP请求并读取包含blob内容的响应流。 You would need to go down this route if the container ACL is
Private
because in this case your requests need to be authenticated and the code above creates an authenticated request. 如果容器ACL为“
Private
则您需要沿着这条路线走,因为在这种情况下,您的请求需要进行身份验证,并且上面的代码创建了经过身份验证的请求。
Question3: Can it be an SSL issue?
问题3:这可能是SSL问题吗? What is the concept of certificates, and how and where to add them?
证书的概念是什么,以及如何以及在何处添加证书? Do I really need them?
我真的需要它们吗? Will I need them later, when I do bigger operations on my blob storage(I want to manage a thousand blobs)?
当我在Blob存储上执行较大的操作(我想管理一千个Blob)时,以后是否需要它们?
No, it is not an SSL issue. 不,这不是SSL问题。 Its an issue with incorrect signature.
这是签名错误的问题。
Finally found the mistake!! 终于发现了错误!!
In the code above , I was using a String "password" as key for my SHA2 在上面的代码中,我使用String“ password”作为我的SHA2的键
base64.decode(key)
It should have been the key associated with my account with AZURE. 它应该是与我的AZURE帐户关联的密钥。 Silly One!!
傻一! Took me 2 weeks to find.
花了我两个星期的时间找到。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.