Azure Java SDK: ServiceException: ForbiddenError:

2019-03-03 12:06发布

Tried the basic location retriever code (shown below)

String uri = "https://management.core.windows.net/";
        String subscriptionId = "XXXXXXXX-5fad-XXXXXX-9dfa-XXXXXX";
         String keyStoreLocation = "D:\\test.jks";
         String keyStorePassword = "123456";

        Configuration config = ManagementConfiguration.configure(
                  new URI(uri), 
                  subscriptionId,
                  keyStoreLocation, // the file path to the JKS
                  keyStorePassword, // the password for the JKS
                  KeyStoreType.jks // flags that I'm using a JKS keystore
                ); 


        ManagementClient client = ManagementService.create(config);
        // get the list of regions
        LocationsListResponse response = client.getLocationsOperations().list();
        ArrayList<Location> locations = response.getLocations();
        // write them out
        for( int i=0; i<locations.size(); i++){
          System.out.println(locations.get(i).getDisplayName());

    }

and It works fine. But when I try to create the ComputeManagementClient and try to restart a VM

ComputeManagementClient computeManagementClient = ComputeManagementService.create(config);
        VirtualMachineOperations virtualMachinesOperations= computeManagementClient.getVirtualMachinesOperations();
virtualMachinesOperations.restart("SQLVM", "sqlvm.cloudapp.net");

I'm getting the certificate error.

Exception in thread "main" java.util.concurrent.ExecutionException: com.microsoft.windowsazure.exception.ServiceException: ForbiddenError: The server failed to authenticate the request. Verify that the certificate is valid and is associated with this subscription.
    at java.util.concurrent.FutureTask.report(FutureTask.java:122)
    at java.util.concurrent.FutureTask.get(FutureTask.java:188)
    at com.microsoft.azure.management.compute.VirtualMachineOperationsImpl.restart(VirtualMachineOperationsImpl.java:9973)
    at com.microsoft.azure.compute.RestartVMExample.main(RestartVMExample.java:84)

PS: I created a the .cer from Java Keystore and uploaded into Azure with no issues.

Any clues what is happening?

1条回答
家丑人穷心不美
2楼-- · 2019-03-03 12:57

The issue is caused by using the incorrect Azure Java SDK libraries. When I used the maven dependencies in the file pom.xml below, I reproduced the same exception.

<dependency>
   <groupId>com.microsoft.azure</groupId>
   <artifactId>azure-mgmt-compute</artifactId>
   <version>0.8.3</version>
</dependency>

The library supply the VM restart function need two arguments: resource group name and vm name. But the API of library azure-mgmt-compute is used for Azure Resource Management.

To restart VM, you need to use the API of library azure-svc-mgmt-compute for Azure Service Management if you used JKS certificates. The Class VirtualMachineOperations supply the same name function restart need three arguments: service name, deployment name and vm name. You can find these names from Cloud Service dashboard on Azure Portal. In your issue code, the vm name should be "sqlvm".

The right maven pom.xml for dependencies as below:

<dependency>
   <groupId>com.microsoft.azure</groupId>
   <artifactId>azure-svc-mgmt</artifactId>
   <version>0.8.3</version>
</dependency>
<dependency>
   <groupId>com.microsoft.azure</groupId>
   <artifactId>azure-svc-mgmt-compute</artifactId>
   <version>0.8.3</version>
</dependency>

And the code as below

virtualMachinesOperations.restart("<service name: sqlvm>", "<deployment name: sqlvm>", "<vm name: sqlvm>");

The steps below for genkeypair by using Java Keytool in the path JAVA_HOME/bin:

keytool -genkeypair -alias keyfile -keyalg RSA -keystore <KeyStore.jks> 
-keysize 2048 -storepass "<password>"

keytool -v -export -file <KeyStore.cer> -keystore KeyStore.jks -alias keyfile

My code:

String uri = "https://management.core.windows.net/";
String subscriptionId = "<subscription_id>";
String keyStoreLocation = "KeyStore.jks";
String keyStorePassword = "<password>";

Configuration config = ManagementConfiguration.configure(
       new URI(uri), 
       subscriptionId,
       keyStoreLocation, // the file path to the JKS
       keyStorePassword, // the password for the JKS
       KeyStoreType.jks // flags that I'm using a JKS keystore
    ); 
ComputeManagementClient computeManagementClient = ComputeManagementService.create(config);
VirtualMachineOperations virtualMachinesOperations = computeManagementClient.getVirtualMachinesOperations();
virtualMachinesOperations.restart("petercore", "petercore", "petercore");
查看更多
登录 后发表回答