How to run war file on machine of client from another country without having error related to clock/ signature?

瘦欲@ 提交于 2020-01-24 23:27:26

问题


I have eclispe maven project based on Azure services. I want to run it on client's machine who is from another country, so have different time zone.

When I install eclipse on their machine and run all the services, those works fine. But when I added war to apache folder , after running it, it's giving error like :

Make sure the value of Authorization header is formed correctly including the signature.
at com.microsoft.azure.storage.StorageException.translateException(StorageException.java:)

I came to this link and I think I am having almost same type of error :

StorageException for azure blob with java

Please tell me how to solve this and how to make clock 'slow' as mentioned in the answer of provided link.

Here is the code : (See the code in else loop from first method. It's blob related code.)

@Override
    public JSONObject syncFiles(JSONObject jsonInput) throws InvalidKeyException, URISyntaxException {
        if (jsonInput.containsKey("accountName")) {
            CloudFileClient fileClient = null;
            String storageConnectionString = "DefaultEndpointsProtocol=https;AccountName="
                    + jsonInput.get("accountName") + ";" + "AccountKey=" + jsonInput.get("accountKey");
            System.out.println(storageConnectionString);
            CloudStorageAccount storageAccount = CloudStorageAccount.parse(storageConnectionString);
            JSONObject jsonOutput = new JSONObject();
            ArrayList fileList = new ArrayList<>();
            try {
                // fileClient =
                // FileClientProvider.getFileClientReference(jsonOutput);
                fileClient = storageAccount.createCloudFileClient();
                String directoryName = jsonInput.get("directoryStructure").toString();

                String[] directoryNameArray = directoryName.split("\\s*/\\s*");
                System.out.println(directoryNameArray.length);

                CloudFileShare share = fileClient.getShareReference(directoryNameArray[0].toLowerCase()
                        .replaceAll("[-+.^:,!@#$%&*()_~`]", "").replaceAll("\\s+", ""));
                if (share.createIfNotExists()) {
                    System.out.println("New share created named as " + directoryNameArray[0].toLowerCase()
                            .replaceAll("[-+.^:,!@#$%&*()_~`]", "").replaceAll("\\s+", ""));
                }
                CloudFileDirectory rootDir = share.getRootDirectoryReference();
                for (int i = 0; i < directoryNameArray.length; i++) {
                    String directoryToCreate = directoryNameArray[i];
                    CloudFileDirectory directory = rootDir.getDirectoryReference(directoryToCreate);

                    String directoryNameToListFiles = directory.getName();
                    if (i == directoryNameArray.length - 1) {
                        for (ListFileItem fileItem : directory.listFilesAndDirectories()) {
                            boolean isDirectory;
                            if (isDirectory = fileItem.getClass() == CloudFileDirectory.class) {
                                System.out.println("Directory Exists Here");
                            } else {
                                System.out.println("Name with files :" + fileItem.getUri().toString());
                                String downloadLocation = "/home/zcon/AzureDownloadedFiles";
                                String fileName[] = fileItem.getUri().toString().split("\\s*/\\s*");
                                for (int j = 0; j < fileName.length; j++) {
                                    if (j == fileName.length - 1) {
                                        String fileNameWithExtension = fileName[j];
                                        File f = new File(downloadLocation + "/" + fileNameWithExtension);
                                        String DownloadTo = f.toString();
                                        f.createNewFile();
                                        CloudFile cloudFile = directory
                                                .getFileReference(fileNameWithExtension.replaceAll("%20", " "));
                                        System.out.println("fileName===========" + fileNameWithExtension);
                                        String tokenKey = testFileSAS(share, cloudFile);
                                        cloudFile.downloadToFile(DownloadTo);
                                        fileList.add(fileItem.getUri().toString() + "?" + tokenKey);
                                        f.delete();
                                    }
                                }
                            }
                        }
                    }
                    rootDir = directory;
                }
                ArrayList fileNamesList = new ArrayList<>();
                for (int i = 0; i < fileList.size(); i++) {
                    String fileName[] = fileList.get(i).toString().split("\\s*/\\s*");
                    for (int j = 0; j < fileName.length; j++) {
                        if (j == fileName.length - 1) {
                            String fileNameReturn = fileName[j];
                            String[] fileNameReturnArray = fileNameReturn.split("\\.");
                            fileNamesList.add(fileNameReturnArray[0].replace("%20", " "));
                        }
                    }
                }
                jsonOutput.put("fileNamesList", fileNamesList);
                jsonOutput.put("fileList", fileList);
                jsonOutput.put("status", "successful");
            } catch (Exception e) {
                System.out.println("Exception is " + e.toString());
                jsonOutput.put("status", "unsuccessful");
                jsonOutput.put("exception", e.toString());
                e.printStackTrace();
            }
            return jsonOutput;
        } else {

            CloudBlobClient blobClient = null;
            String storageConnectionString = "DefaultEndpointsProtocol=https;AccountName="
                    + jsonInput.get("blobAccountName") + ";" + "AccountKey=" + jsonInput.get("blobAccountKey");
            System.out.println(storageConnectionString);
            CloudStorageAccount storageAccount = CloudStorageAccount.parse(storageConnectionString);
            JSONObject jsonOutput = new JSONObject();
            ArrayList fileList = new ArrayList<>();
            ArrayList fileNamesList = new ArrayList<>();
            ArrayList blobItemList = new ArrayList<>();

            try {
                blobClient = storageAccount.createCloudBlobClient();
                String directoryName = jsonInput.get("directoryStructure").toString();
                String[] directoryNameArray = directoryName.split("\\s*/\\s*");
                CloudBlobContainer container = blobClient.getContainerReference(directoryNameArray[0].toLowerCase()
                        .replaceAll("[-+.^:,!@#$%&*()_~`]", "").replaceAll("\\s+", ""));
                if (container.createIfNotExists()) {
                    System.out.println("New share created named as " + directoryNameArray[0].toLowerCase()
                            .replaceAll("[-+.^:,!@#$%&*()_~`]", "").replaceAll("\\s+", ""));
                }
                // CloudBlockBlob blob =
                // container.getBlockBlobReference(jsonInput.get("directoryStructure")+"/"+jsonInput.get("fileToCopy"));
                CloudBlobDirectory directoryOfFile = container
                        .getDirectoryReference(jsonInput.get("directoryStructure").toString());
                for (ListBlobItem blobItem : directoryOfFile.listBlobs()) {
                    // System.out.println(blobItem.getUri());
                    // fileList.add(blobItem.getUri());
                    blobItemList.add(blobItem);

                }

                for(int  q= 0; q<blobItemList.size(); q++){
                    if(blobItemList.get(q).getClass()==CloudBlobDirectory.class)
                    {
                        blobItemList.remove(q);
                    }
                }
                System.out.println(blobItemList);
                for (int l = 0; l < blobItemList.size(); l++) {
                    CloudBlob blob = (CloudBlob) blobItemList.get(l);
                    if (blob.getUri().toString().contains("Temp.txt")) {
                        System.out.println("Temp file was skipped");
                    } else {
                        String tokenKey = testBlobSaS(blob, container);
                        fileList.add(blob.getUri().toString() + "?" + tokenKey);
                    }
                }
                System.out.println("size of blobItemList is=============" + blobItemList.size());

                for (int k = 0; k < fileList.size(); k++) {
                    String fileItem = fileList.get(k).toString();
                    String fileName[] = fileItem.split("\\s*/\\s*");

                    for (int j = 0; j < fileName.length; j++) {
                        if (j == fileName.length - 1) {
                            String fileNameWithExtension = fileName[j];
                            String[] parts = fileNameWithExtension.split("\\?");
                            System.out.println("fileName===========" + fileNameWithExtension);
                            fileNamesList.add(parts[0].replace("%20", " "));
                        }
                    }
                }
                jsonOutput.put("fileList", fileList);
                jsonOutput.put("fileNamesList", fileNamesList);
                jsonOutput.put("status", "successful");
                System.out.println(fileList);
                return jsonOutput;
            } catch (Exception e) {
                System.out.println("Exception is " + e.toString());
                jsonOutput.put("status", "unsuccessful");
                jsonOutput.put("exception", e.toString());
                e.printStackTrace();
            }
            return jsonOutput;
        }

    }

Method to create BlobSAS :

@Test
    // @Category(SlowTests.class)
    public String testBlobSaS(CloudBlob blob, CloudBlobContainer container) throws InvalidKeyException,
            IllegalArgumentException, StorageException, URISyntaxException, InterruptedException {
        SharedAccessBlobPolicy sp = createSharedAccessBlobPolicy(
                EnumSet.of(SharedAccessBlobPermissions.READ, SharedAccessBlobPermissions.LIST), 100);
        BlobContainerPermissions perms = new BlobContainerPermissions();

        perms.getSharedAccessPolicies().put("readperm", sp);
        container.uploadPermissions(perms);
        // Thread.sleep(30000);
        String sas = blob.generateSharedAccessSignature(sp, null);

        CloudBlockBlob sasBlob = new CloudBlockBlob(
                new URI(blob.getUri().toString() + "?" + blob.generateSharedAccessSignature(null, "readperm")));
        sasBlob.download(new ByteArrayOutputStream());

        // do not give the client and check that the new blob's client has the
        // correct perms
        CloudBlob blobFromUri = new CloudBlockBlob(
                PathUtility.addToQuery(blob.getStorageUri(), blob.generateSharedAccessSignature(null, "readperm")));
        assertEquals(StorageCredentialsSharedAccessSignature.class.toString(),
                blobFromUri.getServiceClient().getCredentials().getClass().toString());

        // create credentials from sas
        StorageCredentials creds = new StorageCredentialsSharedAccessSignature(
                blob.generateSharedAccessSignature(null, "readperm"));
        CloudBlobClient bClient = new CloudBlobClient(sasBlob.getServiceClient().getStorageUri(), creds);

        CloudBlockBlob blobFromClient = bClient.getContainerReference(blob.getContainer().getName())
                .getBlockBlobReference(blob.getName());
        assertEquals(StorageCredentialsSharedAccessSignature.class.toString(),
                blobFromClient.getServiceClient().getCredentials().getClass().toString());
        assertEquals(bClient, blobFromClient.getServiceClient());
        return sas;

    }

Method to create shared access blob policy :

private final static SharedAccessBlobPolicy createSharedAccessBlobPolicy(EnumSet<SharedAccessBlobPermissions> sap,
            int expireTimeInSeconds) {

        Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
        cal.setTime(new Date());
        cal.add(Calendar.YEAR, expireTimeInSeconds);
        SharedAccessBlobPolicy policy = new SharedAccessBlobPolicy();
        policy.setPermissions(sap);
        policy.setSharedAccessExpiryTime(cal.getTime());
        return policy;

    }

What changes I should make here?


回答1:


I have faced similar problem before. What you need to do is , make your code comfortable for all the time zones like GMT,IST,EST etc. Because when you upload war in server of another country, your code must be 'clever' enough to understand time zone of that country !

So here is what you can do :

Step 1:

In third part of your code , try replaceing "UTC" by your client machine's timezone like GMT,EST etc.

If that works (and I am pretty much sure that it will work fine) , go for

Step 2:

First of all we will code something that gives you current time zone in String like "Indian Standard Time" or "European Standard Time" etc.

Then, we will pick only first letters from all words and make a String like "IST" or "EST".

At last, we will pass this String at place where you wrote "UTC" in third part of your code.

So, here is the code :

private final static SharedAccessBlobPolicy createSharedAccessBlobPolicy(EnumSet<SharedAccessBlobPermissions> sap,
            int expireTimeInSeconds) {
        Calendar now = Calendar.getInstance();
        TimeZone timeZone = now.getTimeZone();
        System.out.println("Current TimeZone is : " + timeZone.getDisplayName());
        String x = timeZone.getDisplayName();
        String[] myName = x.split(" ");
        String s = "";
        ArrayList zoneArray = new ArrayList<>();
        char zone = 0;
        for (int i = 0; i < myName.length; i++) {
            s = myName[i];
            System.out.print(s.charAt(0));
            zone = s.charAt(0);
            zoneArray.add(zone);
        }
        String timeZoneCurrent = s;
        String timeZoneDynamic = zoneArray.toString().replace(",", "").replace(" ", "").replace("[", "").replace("]",
                "");
        System.out.println("Value of S==========" + timeZoneDynamic);
        Calendar cal = new GregorianCalendar(TimeZone.getTimeZone(timeZoneDynamic));
        cal.setTime(new Date());
        cal.add(Calendar.YEAR, expireTimeInSeconds);
        SharedAccessBlobPolicy policy = new SharedAccessBlobPolicy();
        policy.setPermissions(sap);
        policy.setSharedAccessExpiryTime(cal.getTime());
        return policy;
    } 

In this, timeZoneDynamic has values like "IST" , "GMT" etc. This logic must work. If have any error, post it in edit. Hope that will work.




回答2:


Without the code it is hard to tell, however there is a chance that the times on the client or at the server are not in utc or wrongly converted.

Check the time and timezones of the machine. If they match, check your code if the utc time or local time is used.




回答3:


Per my experience, the issue was caused by the incorrect code in the method private final static SharedAccessBlobPolicy createSharedAccessBlobPolicy to get the UTC time via Calendar .

As reference, Here is my sample code to get UTC time using Calendar.

Calendar cal = Calendar.getInstance() ;  
// Get the time zone offset
int zoneOffset = cal.get(Calendar.ZONE_OFFSET);  
// Get the daylight-saving time offset 
int dstOffset = cal.get(Calendar.DST_OFFSET);  
// Reduce these offsets above from local time to get UTC time
cal.add(Calendar.MILLISECOND, -(zoneOffset + dstOffset));
System.out.println(cal.getTime());

Then, to add the expire time seconds to get the final date time.



来源:https://stackoverflow.com/questions/44906619/how-to-run-war-file-on-machine-of-client-from-another-country-without-having-err

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!