Encounter CROS error while trying to get key vault secrets in my Angular app(using Msal.js)

72 views Asked by At

I am trying to get key vault secrets in my Azure account. I am using Msal.js for that. I can successfully log in to my app with azure but while I am trying to get secret. Here is my function to get secret:

public getSecret(secretName: string): any {
      const keyVaultUrl = 'https://denemekeyvault.vault.azure.net/';
      const apiUrl = `${keyVaultUrl}secrets/${secretName}?api-version=7.4`;
      console.log(apiUrl);
  
      this.getAccessToken().then(token => {
        const headers = new HttpHeaders({
          'Accept': 'application/json', 
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${token}`,
        });
        
        
  
        console.log("headers", headers.getAll('Authorization'));
  
        this.http.get(apiUrl, { headers: headers }).subscribe(
          response => {
            console.log(response);
          },
          error => {
            console.error('token:'+token+'headers:'+headers+'API çağrısı sırasında hata oluştu:', error);
          }
        );
      });
    }

I tried on Postman to do these actions and i succeed but in Angular I took CORS error.

I expect to get key vault secret but i did not happened beacuse i got CORS error.

1

There are 1 answers

0
Dasari Kamali On

I successfully retrieved the Azure Key Vault Secret using an access token with the backend code in JavaScript and frontend in Angular.

backend :

server.js :

const express = require('express');
const axios = require('axios');

const app = express();

const keyVaultUrl = 'https://<key_vault_name>.vault.azure.net/';
const secretName = '<secret_name>';
const accessToken = '<access_token>';

app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
  next();
});

app.get('/api/secret', async (req, res) => {
  try {
    const response = await axios.get(`${keyVaultUrl}/secrets/${secretName}?api-version=7.0`, {
      headers: {
        'Authorization': `Bearer ${accessToken}`
      }
    });
    res.json({ value: response.data.value }); 
  } catch (error) {
    console.error('Error retrieving secret:', error);
    res.status(500).send('Error retrieving secret');
  }
});

const port = 3000;
app.listen(port, () => {
  console.log(`Server is running on port ${port}`);
});

frontend :

keyvault.service.ts :

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class KeyVaultService {
  private apiUrl = 'http://localhost:3000/api/secret'; 

  constructor(private http: HttpClient) { }

  getSecret(): Observable<any> {
    return this.http.get<any>(this.apiUrl);
  }
}

app.component.ts :

import { Component, OnInit } from '@angular/core';
import { KeyVaultService } from './keyvault.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  secretValue: string = ''; 

  constructor(private keyVaultService: KeyVaultService) {}
  ngOnInit(): void {
    this.keyVaultService.getSecret().subscribe(
      (data: any) => { 
        this.secretValue = data.value; 
      },
      (error) => {
        console.error('Error retrieving secret:', error);
      }
    );
  }
}

app.module.ts :

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule } from '@angular/common/http';

import { AppComponent } from './app.component';
import { KeyVaultService } from './keyvault.service';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule
  ],
  providers: [KeyVaultService],
  bootstrap: [AppComponent]
})
export class AppModule { }

app.component.html :

<div *ngIf="secretValue">
  <p>Secret Value: {{ secretValue }}</p>
</div>

I granted access to my Azure AD app (which utilized an access token) to retrieve the secret from the Azure Key Vault, as demonstrated below:

enter image description here

Output :

The backend code ran successfully, as shown below.

enter image description here

I retrieved the Azure Key Vault secret in the browser, as shown below.

http://localhost:3000/api/secret
{
    "value": "Hi Kamali"
}

enter image description here

Then, I started my frontend code, as shown below.

enter image description here

I successfully retrieved the Azure Key Vault secret in the browser, as shown below.

http://localhost:4200/
Secret Value: Hi Kamali

enter image description here