Issues with Authenticating GET Operation Status using Management Certificate in Azure

60 views Asked by At

I'm encountering authentication problems while attempting to perform a GET operation statuswithin Azure using a management certificate. I followed the steps outlined in this documentation to generate an SSL certificate and successfully uploaded it to Azure Key Vault.

However, upon using the uploaded certificate for authentication, I keep receiving the following error:

<Code>ForbiddenError</Code>

<Message>The server failed to authenticate the request. Verify that the certificate is valid and is associated with this subscription.</Message>

I referred to this Azure documentation for uploading the certificate to Key Vault. However, I'm stuck at the 7th step, particularly regarding the configuration file's placement and its contents.

Currently, I'm using a Java configuration class to handle SSL connections and certificate authentication within my application. Here's an excerpt of my Java configuration:

 @Bean("SSlConfig")
    public RestTemplate customRestTemplate() {
        char[] emptyPass = {};

        // Get the certificate bytes from the retrieved certificate
        byte[] certBytes = certificate.getCer(); 

        try {
                        // Create a Certificate instance from the certificate bytes
                        CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
                        ByteArrayInputStream inputStream = new ByteArrayInputStream(certBytes);
                        Certificate certificate = certificateFactory.generateCertificate(inputStream);

                        // Retrieving private key
                        String base64PrivateKey = certifPrivateKey.getValue();
                        byte[] rawPrivateKey = Base64.getDecoder().decode(base64PrivateKey);



                        // Create KeyStore and load the certificate
                        KeyStore rsaKeyGenerator  = KeyStore.getInstance(KeyStore.getDefaultType());
                        ByteArrayInputStream keyStream = new ByteArrayInputStream(rawPrivateKey);
                        rsaKeyGenerator .load(keyStream, null);
                        close(keyStream);
                        Key rsaPrivateKey = rsaKeyGenerator .getKey(rsaKeyGenerator .aliases().nextElement(), emptyPass);
                        // Retrieving private key

                        // Importing certificate and private key into the KeyStore
                        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
                        keyStore.load(null);
                        keyStore.setKeyEntry("my-service-certificate", rsaPrivateKey, emptyPass, new Certificate[] {certificate});
                        // Importing certificate and private key into the KeyStore

                        SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(
                                new SSLContextBuilder()
                                        .loadTrustMaterial(null, new TrustAllStrategy())
                                        .loadKeyMaterial(keyStore, emptyPass)
                                        .build(),
                                NoopHostnameVerifier.INSTANCE);


            HttpClientConnectionManager connectionManager = PoolingHttpClientConnectionManagerBuilder.create()
                    .setSSLSocketFactory(socketFactory)
                    .build();


            CloseableHttpClient httpClient = HttpClients.custom()
                    .setConnectionManager(connectionManager)
                    .evictExpiredConnections()
                    .setKeepAliveStrategy((httpResponse, httpContext) -> TimeValue.ofSeconds(10 * 1000))
                    .build();

            ClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);


            return new RestTemplate(requestFactory);
                    }catch (IOException | CertificateException
                            | NoSuchAlgorithmException | UnrecoverableKeyException
                            | KeyStoreException | KeyManagementException e) {
            log.error("Error!!!");
        }
        return null;
    }

And this is how I'm implementing the Get Operation Status:

  HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.add("x-ms-version", "2009-10-01");

            // Set the request body
            HttpEntity<Object> entity = new HttpEntity < > (headers);

            // Build the URL
            String encodedPolicyAssignmentName = URLEncoder.encode(x_ms_request_id, StandardCharsets.UTF_8.toString());
            String url = "https://management.core.windows.net/{subscriptionId}/operations/"+encodedPolicyAssignmentName;
    // Send the HTTP request
            ResponseEntity < String > response = restTemplate.exchange(url, HttpMethod.GET, entity, String.class);

I'm seeking guidance on how to correctly utilize the uploaded SSL certificate from Azure Key Vault for authentication purposes in my Java code. Specifically, I'd appreciate clarification on the 7th step of the Azure documentation regarding Service Configuration (.cscfg) file to link the certificat with my subscription .

Also, could the migration from Azure Cloud Services (classic) to Cloud Services (extended support) potentially affect the functionality or accessibility of the Azure Get Operation Status API? Are there any specific considerations or changes related to this API that need to be taken into account during or after the migration process?

What I did :

  • Generated an SSL certificate following the steps outlined in the Azure documentation.

  • Uploaded the generated certificate to Azure Key Vault successfully.

  • Configured my Java application to retrieve and utilize the certificate from Azure Key Vault for authentication during GET operations within Azure services.

  • Implemented the SSL configuration in Java code (provide relevant code snippets).

0

There are 0 answers