Search code examples
angulardownloadazure-storage

download large files from azure storage blob to angular client in secure way


hello i try to find a way to download files from azure storage to angaular client that deploayed to web app in azure , till now the app is authenticate the users in fornt of AAD using msal and after authentication i get an id token , know i want that authenticated user will be able to download file from azure storage i configured roles to my users in my storage account using rbac but i don't know how to do secure connection to download the files from azure , do i need a server if though i need to download the files both at server side and client side?or maybe i can do it only in the client side? please help me to solve this problem , regards , gal


Solution

  • We can directly download file in client with package @azure/storage-blob. Meanwhile, you have configured Azure AD auth in your angular application. You can use Azure AD auth to access Azure blob storage. But please note that we need to assign special Azure RABC (Storage Blob Data Reader) role to the users if we use the way. For more details, pleas refer to here

    For example

    1. Install sdk
    npm install @azure/storage-blob @azure/core-http
    
    1. Implement TokenCredential with token you required from msal
    import {
      TokenCredential,
      GetTokenOptions,
      AccessToken,
    } from '@azure/core-http';
    
    export class MyCredential implements TokenCredential {
      private tokens: string;
      constructor(token: string) {
        this.tokens = token;
      }
      public async getToken(
        scopes: string | string[],
        options?: GetTokenOptions
      ): Promise<AccessToken> {
        var result = new MyToken(this.tokens);
    
        console.log(result);
        return result;
      }
    }
    
    class MyToken implements AccessToken {
      token: string;
      expiresOnTimestamp: number;
    
      constructor(token: string) {
        this.token = token;
      }
    }
    
    
    1. Downalod
    import { AuthResponse } from 'msal';
    import { HttpClient } from '@angular/common/http';
    import { MyCredential } from './MyCredential';
    import { BlobServiceClient } from '@azure/storage-blob';
    
    @Component({
      selector: 'app-download',
      templateUrl: './download.component.html',
      styleUrls: ['./download.component.css'],
    })
    export class DownloadComponent implements OnInit {
      constructor(private msalService: MsalService, private http: HttpClient) {}
    
      ngOnInit(): void {}
    
      async download(data) {
        try {
          console.log(data);
          let tokenResponse: AuthResponse;
          if (this.msalService.getAccount()) {
            tokenResponse = await this.msalService.acquireTokenSilent({
              scopes: ['https://storage.azure.com/user_impersonation'],
            });
          } else {
            tokenResponse = await this.msalService.acquireTokenPopup({
              scopes: ['https://storage.azure.com/user_impersonation'],
            });
          }
    
          //console.log(tokenResponse.accessToken);
          var cer = new MyCredential(tokenResponse.accessToken);
          var client = new BlobServiceClient(
            'https://<accountName>.blob.core.windows.net/',
            cer
          );
    
          var ca = client.getContainerClient(data.container);
          var blob = ca.getBlobClient(data.fileName  );
    var properties = await blob.getProperties();
          var result = await blob.download(0, properties.contentLength, {
            onProgress: (progress) => {
              console.log(`You have download ${progress.loadedBytes} bytes`);
            },
            maxRetryRequests:10
          });
          // it will return  browser Blob
          var fileBlob = await result.blobBody;
          const url = window.URL.createObjectURL(fileBlob);
          window.open(url);
        } catch (error) {
          console.log(error);
        }
      }
    }
    

    enter image description here