Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

The ultimate Microsoft Fabric, Power BI, Azure AI & SQL learning event! Join us in Las Vegas from March 26-28, 2024. Use code MSCUST for a $100 discount. Register Now

Reply
ericOnline
Post Patron
Post Patron

How to display an image from Azure Blob Storage in Power BI Report (no SAS tokens)?

Hello,

 

Goal: Use an App ID to retrieve images from Azure Blob Storage and show them in a grid in a Power BI report.

 

Rationale: Because I cannot generate a long-lived SAS token per my orgs security requirements and I want to simplify permissions by using a single App ID.

 

So I...

- registered an App with Azure Active Directory

- created a `client_secret`

- then used this information in PowerQuery to send an OAUTH token request to the AAD auth endpoint

- and receive a Bearer token

- I also granted the App ID `Storage Blob Data Contributor` role to the Azure Blob Storage Container where images are stored

 

GetOATHToken Function PowerQuery:

- This results in a valid Bearer token to use in the Authorization header for subsequent GET Blob requests

 

= let
    url = "https://login.microsoftonline.com/<my-tenant-id>/oauth2/v2.0/token",
    headers = [
        #"Content-Type" = "application/x-www-form-urlencoded"
    ],
    content =
    [
        grant_type = "client_credentials",
        scope = "https://<my-account>.blob.core.windows.net/.default",
        client_id = "<my-id>",
        client_secret = "<my-secret>"
    ],
    webdata = Web.Contents(url, [Headers=headers,Content=Text.ToBinary(Uri.BuildQueryString(content))]),
    response = Json.Document(webdata),
    token = response[access_token]
    in
    token

 

 

ericOnline_0-1679545255566.png

 

I then...

- used the Azure Storage REST API and the results from the above Function call to request one of the blob images

- and this is successful

 

GetImage request PowerQuery:

- This results in an image

 

= let 
    url = "https://<my-account>.blob.core.windows.net/<my-container>/<folder1>/<folder2>/<actual-image>.jpg",
    headers = [
        #"x-ms-version" = "2018-03-28",
        #"Authorization" = "Bearer " & GetOAUTHToken()
    ],
    webdata = Web.Contents(url, [Headers=headers])
    in
    webdata

 

 

ericOnline_1-1679545372726.png

 

Now what? 

 

1. How do I do this for ALL images in a certain blob folder, not just a single image?

2. How do I display the retrieved images and show them in my report?

 

Thank you

 

 

7 REPLIES 7
ericOnline
Post Patron
Post Patron

Hm...well, I was able to create an Azure Function to create short-lived SAS tokens to Storage Blobs. 

 

Trigger: HTTP GET request

 

Input: Url-encoded blob URL, appended as a parameter to the GET request

Example

 

https://<my-service>.azurewebsites.net/api/<my-api>?url=https%3A%2F%2F<blob-account>.blob.core.windows.net%2F<container-name>%2F<folder-1>%2F<folder-2>%2F<blob-name>.jpg

 

 

Output: Blob URL with short-lived SAS token appended

Example

 

https://<blob-account>.blob.core.windows.net/<container-name>/<folder-1>/<folder-2>/<blob-name>.jpg?se=<expiration>&sp=<perms>&sv=<version>&sr=<resource>&sig=<signature>

 

 

Goal:

- Show a gallery of thumbnail images in the report.

- When user clicks on an image, the full size image opens in a new browser tab.

 

I'm able to create a Blank Query and trigger the Azure Function with this...

= let
    url = "https://<my-service>.azurewebsites.net/api/<my-api>?url=https%3A%2F%2F<account-name>.blob.core.windows.net%2F<container-name>%2F<folder-1>%2F<folder-2>%2F<blob-name>.jpg",
    headers = [
        #"x-functions-key" = "<function-key>"
    ],
    webdata = Web.Contents(url, [Headers=headers]),
    token = Table.FromColumns({Lines.FromBinary(webdata,null,null,65001)})
    in
    token

 

Ideas? Thank you!

You would feed that set of URLs to the Image viewer visual. Or you can handcraft your HTML and use the HTML5 viewer visual etc.

All I have at this moment is a Blank Query that returns a Blob URL + SAS Token.

 

Seems quite difficult to:

- Connect to the Azure Blob Storage

- URL-encode all the images

- Somehow append the encoded URL's to the service GET request

- Call the service to show the thumbnails

- Then make each thumbnail itself a hyperlink that, when clicked, opens blob image in a new browser tab

lbendlin
Super User
Super User

1.  Create a table with a column that holds the URL for each of the images.  Call the second Power Query as a function with the URL as the parameter and the binary as the result.  Convert the binary to Base64.  Then in Power BI specify the field as imageURL and display as needed.

 

2. Chris Webb's BI Blog: Storing Large Images In Power BI Datasets (crossjoin.co.uk)

@lbendlin , thanks for the suggestion, however saving each "chunk" of an image's base64-encoded text, into a separate row of a data table, then using DAX to piece it back together is a little too deep for me.

 

I'm going to create an Azure Function instead that takes the URL of the blob and displays it in the user's browser. 

You can try that. Be aware of potential authentication issues for report end users - something you avoid with the embedding.

The Function will use an App ID (or a Connection String) that is authorized to generate short-lived SAS tokens, apply them to the image URLs, then open the full size images in the browser. At least thats the thought ;).

Helpful resources

Announcements
Fabric Community Conference

Microsoft Fabric Community Conference

Join us at our first-ever Microsoft Fabric Community Conference, March 26-28, 2024 in Las Vegas with 100+ sessions by community experts and Microsoft engineering.