在Azure上设置SAS,策略和CORS的Java客户端

时间:2015-11-25 20:06:16

标签: java azure cors

我尝试使用Java客户端在Azure上设置CORS属性。执行代码后,我运行HTML5代码上传文件并在chrome javascript控制台中面临以下错误:

  

最大块大小= 47276

     

总积数= 1

     

的https:myacc.blob.core.windows.net/mycon/ch1.jpg SR = C&安培; SV = 2015年4月5日&安培; SIG = djbVxIBlyVy18bV0SkqNSLql1n9efAVcYnGy3VsGKis%3D&安培; SI =冠军

     

当前文件指针= 0字节读取= 47276

     

阻止id = block-000000

     

的https:myacc.blob.core.windows.net/mycon/ch1.jpg SR = C&安培; SV = 2015-0 ... kqNSLql1n9efAVcYnGy3VsGKis%3D&安培; SI =冠军&安培;可比=块&安培;块标识= YmxvY2stMDAwMDAw

     

无法加载资源:服务器响应状态为403(未启用CORS或未找到此请求的匹配规则。)

     

XMLHttpRequest无法加载   HTTPS:?myacc.blob.core.windows.net/mycon/ch1.jpg SR = C&安培; SV = 2015-0 ... kqNSLql1n9efAVcYnGy3VsGKis%3D&安培; SI =健康&安培;可比=块&安培;块标识= YmxvY2stMDAwMDAw

     

对预检请求的响应未通过访问控制检查:否' Access-Control-Allow-Origin'标题出现在请求的上   资源。 Origin' file://'因此不允许访问。该   响应有HTTP状态码403。

我想知道为什么在Java客户端成功执行后它没有设置CORS?另外,我如何验证规则政策" champ"如果我生成的SAS正确并且创建了CORS属性

,则配置正确

这是Java客户端代码:

public class CORS_and_SAS {
public static void main(String[] args) {
    // Define the connection-string with your values
    final String storageConnectionString ="DefaultEndpointsProtocol=http;" + "AccountName=myacc;" + "AccountKey=B2q4AGp6YoRsTREXIkOv3e/Sxf46YzqzfnM9F8U+o7VA5Y3EiKc+CuritnvuyZxGXKNOQ5nJy2KfkniF970on1dQ==";
    try {
        // Retrieve storage account from connection-string.
        CloudStorageAccount storageAccount = CloudStorageAccount.parse(storageConnectionString);

        // Create the blob client.
       CloudBlobClient blobClient = storageAccount.createCloudBlobClient();

       // Get a reference to a container.
       // The container name must be lower case
       CloudBlobContainer container = blobClient.getContainerReference("mycon");

       // Create the container if it does not exist.
        //container.createIfNotExists();
       // Set CORS support
       //ServiceProperties blobServiceProperties = blobClient.GetServiceProperties();
       ServiceProperties propers = getCORS();
       blobClient.uploadServiceProperties(propers);
        SharedAccessBlobPolicy policy = new SharedAccessBlobPolicy();
          GregorianCalendar calendar = 
             new GregorianCalendar(TimeZone.getTimeZone("UTC"));
          calendar.setTime(new Date());
          policy.setSharedAccessStartTime(calendar.getTime()); //Immediately applicable
          calendar.add(Calendar.HOUR, 3000); //Applicable time-span is 3000 hours
          policy.setSharedAccessExpiryTime(calendar.getTime());           
          policy.setPermissions(EnumSet.of(SharedAccessBlobPermissions.READ, 
             SharedAccessBlobPermissions.WRITE, SharedAccessBlobPermissions.DELETE, 
             SharedAccessBlobPermissions.LIST));
          BlobContainerPermissions containerPermissions = new BlobContainerPermissions();
          //Private container with no access for anonymous users
          containerPermissions.setPublicAccess(BlobContainerPublicAccessType.OFF);
          //Name the shared access policy: heath
          containerPermissions.getSharedAccessPolicies().put("champ", policy);
          container.uploadPermissions(containerPermissions);
          //Generate the policy SAS string for heath access
          String sas = container.generateSharedAccessSignature(
             new SharedAccessBlobPolicy(),"champ");           
          System.out.println("The stored access policy signature:");
          System.out.println(sas);
    } catch (Exception e) {
        // Output the stack trace.
        e.printStackTrace();
    }
}

private static ServiceProperties getCORS() {
    // TODO Auto-generated method stub
    ServiceProperties propers = new ServiceProperties();
    CorsProperties corsprop = propers.getCors();

    CorsRule cr = new CorsRule();

    List<String> allowedHeaders = new ArrayList<String>();
    allowedHeaders.add("x-ms-*");
    List<String> exposedHeaders = new ArrayList<String>();
    exposedHeaders.add("x-ms-*");

    cr.setAllowedHeaders(allowedHeaders);
    cr.setExposedHeaders(exposedHeaders);
    EnumSet<CorsHttpMethods> allowedMethod = EnumSet.of(CorsHttpMethods.PUT,CorsHttpMethods.GET,CorsHttpMethods.POST,CorsHttpMethods.HEAD,CorsHttpMethods.DELETE);
    //EnumSet<CorsHttpMethods> allowedMethod1 = EnumSet.of(CorsHttpMethods.GET);
    cr.setAllowedMethods(allowedMethod);

    List<String> allowedOrigin = new ArrayList<String>();
    allowedOrigin.add("*");
    cr.setAllowedOrigins(allowedOrigin);
    cr.setMaxAgeInSeconds(600);

    corsprop.getCorsRules().add(cr);

    //corsprop.getCorsRules().add(cr);
    propers.setCors(corsprop);
    return propers;
}
}

1 个答案:

答案 0 :(得分:0)

我尝试重现该问题,并仔细检查了Java客户端代码&amp; JS控制台中的错误。我发现问题是由上传文件URL使用blob容器共享访问签名引起的。

以下是您修改的Java代码。

private static final String accountName = "<account-name>";
private static final String accountKey = "<account-key>";
private static final String connectionStringTemplate = "DefaultEndpointsProtocol=http;AccountName=%s;AccountKey=%s";
private static final String containerName = "<block-blob-container-name>";
private static final String blobFileName = "<blob-file-name>";

public static void main(String[] args) throws InvalidKeyException, URISyntaxException, StorageException {
    String connectionString = String.format(connectionStringTemplate, accountName, accountKey);
    CloudStorageAccount account = CloudStorageAccount.parse(connectionString);
    CloudBlobClient blobClient = account.createCloudBlobClient();
    /*
     * Enable CORS
     */
    // CORS should be enabled once at service startup
    // Given a BlobClient, download the current Service Properties
    ServiceProperties blobServiceProperties = blobClient.downloadServiceProperties();
    // Enable and Configure CORS
    CorsProperties cors = new CorsProperties();
    CorsRule corsRule = new CorsRule();
    List<String> allowedHeaders = new ArrayList<String>();
    allowedHeaders.add("*");
    EnumSet<CorsHttpMethods> allowedMethods = EnumSet.of(CorsHttpMethods.PUT, CorsHttpMethods.GET, CorsHttpMethods.HEAD, CorsHttpMethods.POST);
    System.out.println(Arrays.toString(allowedMethods.toArray()));
    List<String> allowedOrigins = new ArrayList<String>();
    allowedOrigins.add("*");
    List<String> exposedHeaders = new ArrayList<String>();
    exposedHeaders.add("*");
    int maxAgeInSeconds = 1800;
    corsRule.setAllowedHeaders(allowedHeaders);
    corsRule.setAllowedMethods(allowedMethods);
    corsRule.setAllowedOrigins(allowedOrigins);
    corsRule.setExposedHeaders(exposedHeaders);
    corsRule.setMaxAgeInSeconds(maxAgeInSeconds);
    cors.getCorsRules().add(corsRule);
    blobServiceProperties.setCors(cors);
    // Commit the CORS changes into the Service Properties
    blobClient.uploadServiceProperties(blobServiceProperties);
    /*
     * Generate the SAS for the uploading url
     */
    CloudBlobContainer container = blobClient.getContainerReference(containerName);
    CloudBlockBlob blockBlob = container.getBlockBlobReference(blobFileName);
    SharedAccessBlobPolicy sharedAccessBlobPolicy = new SharedAccessBlobPolicy();
    GregorianCalendar calendar = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
    calendar.setTime(new Date());
    sharedAccessBlobPolicy.setSharedAccessStartTime(calendar.getTime());
    calendar.add(Calendar.HOUR, 1);
    sharedAccessBlobPolicy.setSharedAccessExpiryTime(calendar.getTime());
    sharedAccessBlobPolicy.setPermissions(EnumSet.of(SharedAccessBlobPermissions.WRITE));
    String sas = blockBlob.generateSharedAccessSignature(sharedAccessBlobPolicy, null);
    System.out.println(sas);
    String blobUploadSASURL = String.format("https://%s.blob.core.windows.net/%s/%s?%s", accountName, containerName, blobFileName, sas);
    System.out.println(blobUploadSASURL);
}

运行代码并获取上传blob SAS Url作为表单https://<account-name>.blob.core.windows.net/<container>/<blob-file-name>?sig=<SIG>&st=2015-12-01T11%3A51%3A20Z&se=2015-12-01T12%3A51%3A20Z&sv=2015-04-05&sp=r&sr=b

使用带标头x-ms-blob-type: BlockBlob的PUT方法成功上传文件。

有关执行此操作的更多详细信息和示例ajax代码,请参阅Azure存储团队http://blogs.msdn.com/b/windowsazurestorage/archive/2014/02/03/windows-azure-storage-introducing-cors.aspx中的博客。