Как запустить файл war на компьютере клиента из другой страны без ошибок, связанных с часами / подписью?

1

У меня есть проект eclispe maven, основанный на сервисах Azure. Я хочу запустить его на клиентской машине из другой страны, поэтому у вас есть другой часовой пояс.

Когда я устанавливаю eclipse на свой компьютер и запускаю все службы, все работает нормально. Но когда я добавил войну в папку apache, после ее запуска она выдавала ошибку, например:

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

Я пришел к этой ссылке, и я думаю, что у меня такая же ошибка:

StorageException для azure blob с java

Скажите, пожалуйста, как решить эту проблему и как сделать тактику "медленной", как указано в ответе предоставленной ссылки.

Вот код: (См. Код в другом цикле от первого метода. Это код, связанный с blob.)

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

    }

Способ создания 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 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;

    }

Способ создания политики доступа общего доступа:

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;

    }

Какие изменения я должен сделать здесь?

  • 0
    Где именно в вашем коде вы получаете ошибку?
  • 0
    Не уверен, что вы имеете в виду, когда хотите, чтобы часы работали медленно. Но имейте в виду: вы должны устанавливать SAS (или политику) на основе UTC, и вы должны знать о смещении тактовой частоты (то есть, где бы вы ни генерировали SAS, он может иметь смещение тактовой частоты от времени в хранилище Azure.
Показать ещё 8 комментариев
Теги:
azure
maven
blob

3 ответа

1
Лучший ответ

Раньше я сталкивался с подобной проблемой. Что вам нужно сделать, сделайте свой код удобным для всех часовых поясов, таких как GMT, IST, EST и т.д. Потому что, когда вы загружаете войну на сервере другой страны, ваш код должен быть "умным", чтобы понять часовой пояс этой страны !

Итак, вот что вы можете сделать:

Шаг 1:

В третьей части кода попробуйте заменить "UTC" на часовой пояс вашего клиентского компьютера, например GMT, EST и т.д.

Если это работает (и я уверен, что он будет работать нормально), идите

Шаг 2:

Прежде всего, мы будем кодировать что-то, что дает вам текущий часовой пояс в String, например, "Indian Standard Time" или "European Standard Time" и т.д.

Затем мы выберем только первые буквы из всех слов и создадим строку типа "IST" или "EST".

Наконец, мы передадим эту строку в месте, где вы написали "UTC" в третьей части вашего кода.

Итак, вот код:

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

В этом случае timeZoneDynamic имеет такие значения, как "IST", "GMT" и т.д. Эта логика должна работать. Если есть какие-либо ошибки, опубликуйте его в редакции. Надеюсь, что это сработает.

0

По моему опыту, проблема была вызвана неправильным кодом в методе private final static SharedAccessBlobPolicy createSharedAccessBlobPolicy чтобы получить время UTC через Calendar.

В качестве ссылки, вот мой пример кода, чтобы получить время UTC с помощью 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());

Затем, чтобы добавить время истечения времени, чтобы получить окончательное время.

  • 0
    Привет, спасибо за ваше предложение. Но все еще на моей машине, это дает IST и на машине клиента, это дает GMT. Вот почему во время отладки выдает ошибку в строке: sasBlob.download (new ByteArrayOutputStream ()); Ошибка: Исключением является com.microsoft.azure.storage.StorageException: Серверу не удалось аутентифицировать запрос. Убедитесь, что значение заголовка авторизации сформировано правильно, включая подпись. Каково ваше предложение?
0

Без кода трудно сказать, однако есть вероятность, что время на клиенте или на сервере не находится в utc или неправильно преобразовано.

Проверьте время и время работы аппарата. Если они совпадают, проверьте свой код, если используется время utc или местное время.

  • 0
    Я использовал UTC в коде. Что еще проверить на часы на машине?
  • 0
    пожалуйста, смотрите отредактированный вопрос. Благодарю.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню