Hi @Artem Shaturskyi
Welcome to the Microsoft Q&A Platform.
Thank you for reaching out, & I hope you are doing well.
Play your video files using the Storage Account Static Website with Entra ID authentication
by following the steps below.
- Create an app registration by navigating to
Microsoft EntraID > App registrations > New registrations.
- Add the redirect URL as
static website endpoint url
andlocalhost url
below.
- Enable the tokens for auto-authorization in application.
- Configure the storage account with
Entra ID authentication
as below.
- Configure CORS settings with required permissions in storage account.
- Configure the container access level to Private.
Storage account Static Website Url
Upload the index.html file below into the $web
container, and make sure to replace it with your Application ID, Tenant ID, and Storage Website URL.
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Secure Video Gallery</title>
<script src="https://alcdn.msauth.net/browser/2.29.0/js/msal-browser.min.js"></script>
<style>
body {
font-family: Arial, sans-serif;
text-align: center;
}
#video-list {
margin-top: 20px;
}
.video-item {
cursor: pointer;
padding: 10px;
border: 1px solid #ccc;
margin: 5px;
display: inline-block;
background-color: #f9f9f9;
}
.video-item:hover {
background-color: #ddd;
}
video {
width: 80%;
margin-top: 20px;
}
#logout-btn {
display: none; /* Hide logout button initially */
margin-top: 10px;
background-color: red;
color: white;
border: none;
padding: 10px;
cursor: pointer;
}
#auth-message {
margin-top: 15px;
font-weight: bold;
color: green;
display: none; /* Hide the message initially */
}
</style>
</head>
<body>
<h2>Secure Video Gallery</h2>
<button id="login-btn" onclick="signIn()">Sign in with Entra ID</button>
<button id="logout-btn" onclick="signOut()">Sign Out</button>
<div id="auth-message"></div> <!-- Authentication Success Message -->
<div id="video-list">Please sign in to view videos.</div>
<video id="video-player" controls crossorigin="anonymous" preload="auto">
<source id="video-source" src="" type="video/mp4">
Your browser does not support the video tag.
</video>
<script>
// Azure Entra ID Authentication Configuration
const msalConfig = {
auth: {
clientId: "2487cxxxxxxxxxxxxxxx136163cc3502", // Replace with your Azure AD App Registration Client ID
authority: "https://login.microsoftonline.com/<Tenant_ID>", // Replace with your Tenant ID
redirectUri: "https://venkatstofragetest.z13.web.core.windows.net/" // Your Static Website URL
}
};
const msalInstance = new msal.PublicClientApplication(msalConfig);
const blobListUrl = "https://venkatstofragetest.blob.core.windows.net/$web?restype=container&comp=list";
const storageScope = "https://storage.azure.com/user_impersonation"; // OAuth Scope for Azure Storage
function updateUI(isAuthenticated) {
document.getElementById("login-btn").style.display = isAuthenticated ? "none" : "inline-block";
document.getElementById("logout-btn").style.display = isAuthenticated ? "inline-block" : "none";
document.getElementById("auth-message").style.display = isAuthenticated ? "block" : "none";
if (isAuthenticated) {
document.getElementById("auth-message").innerText = "β
Authentication successful.";
} else {
document.getElementById("auth-message").innerText = "";
}
}
async function signIn() {
try {
const response = await msalInstance.loginPopup({
scopes: [storageScope]
});
console.log("β
Signed in:", response.account);
updateUI(true);
fetchVideos(); // Fetch videos after login
} catch (error) {
console.error("π΄ Login failed:", error);
document.getElementById("video-list").innerHTML = `<p>Login failed. Please try again.</p>`;
}
}
async function signOut() {
try {
await msalInstance.logoutPopup();
console.log("β
Signed out");
updateUI(false);
document.getElementById("video-list").innerHTML = `<p>Please sign in to view videos.</p>`;
} catch (error) {
console.error("π΄ Logout failed:", error);
}
}
async function fetchVideos() {
try {
const account = msalInstance.getAllAccounts()[0];
if (!account) {
document.getElementById("video-list").innerHTML = `<p>Please sign in to view videos.</p>`;
return;
}
console.log("πΉ Fetching access token...");
// Acquire Access Token for Blob Storage
const tokenResponse = await msalInstance.acquireTokenSilent({
scopes: [storageScope],
account: account
});
if (!tokenResponse || !tokenResponse.accessToken) {
throw new Error("π΄ Failed to obtain access token.");
}
console.log("β
Access Token Received:", tokenResponse.accessToken);
// Fetch video list with Authentication
const response = await fetch(blobListUrl, {
method: "GET",
mode: "cors",
cache: "no-cache",
headers: {
"Authorization": `Bearer ${tokenResponse.accessToken}`,
"x-ms-version": "2020-06-12",
"Accept": "application/xml"
}
});
if (!response.ok) {
throw new Error(`π΄ HTTP error! Status: ${response.status}`);
}
const text = await response.text();
console.log("πΉ Blob XML Response:", text);
const parser = new DOMParser();
const xml = parser.parseFromString(text, "application/xml");
const blobs = xml.getElementsByTagName("Blob");
let videoList = document.getElementById("video-list");
videoList.innerHTML = ""; // Clear previous list
let videoFound = false;
for (let i = 0; i < blobs.length; i++) {
let fileName = blobs[i].getElementsByTagName("Name")[0].textContent;
let fileUrl = `https://venkatstofragetest.blob.core.windows.net/$web/${encodeURIComponent(fileName)}`;
// Only add MP4 files
if (fileName.toLowerCase().endsWith(".mp4")) {
videoFound = true;
let videoItem = document.createElement("div");
videoItem.className = "video-item";
videoItem.textContent = fileName;
videoItem.onclick = function () {
let videoSource = document.getElementById("video-source");
let videoPlayer = document.getElementById("video-player");
videoSource.src = fileUrl;
videoPlayer.load();
videoPlayer.play(); // Ensure playback starts
};
videoList.appendChild(videoItem);
}
}
if (!videoFound) {
videoList.innerHTML = "<p>No videos found.</p>";
}
} catch (error) {
console.error("π΄ Error fetching video list:", error);
if (error.message.includes("401")) {
document.getElementById("video-list").innerHTML = `<p>Unauthorized. Please check storage permissions.</p>`;
} else if (error.message.includes("403")) {
document.getElementById("video-list").innerHTML = `<p>Forbidden. You may not have access to this storage account.</p>`;
} else if (error.message.includes("CORS")) {
document.getElementById("video-list").innerHTML = `<p>CORS issue detected. Ensure Azure Storage CORS settings are correct.</p>`;
} else {
document.getElementById("video-list").innerHTML = `<p>Error loading videos. Please try again later.</p>`;
}
}
}
// Check if the user is already signed in
window.onload = () => {
const account = msalInstance.getAllAccounts()[0];
if (account) {
console.log("πΉ User already signed in:", account);
updateUI(true);
fetchVideos();
}
};
</script>
</body>
</html>
Once you have completed all the steps, try accessing the static website URL in a browser. You will see the page as shown below.
Azure AD authentication page
Here is the result after signing in with Entra ID authentication.
Note: Make sure to assign the required role to access the Blob, Like Storage Blob Data Contributor
Here is the result if someone without the required role tries to access it.
If you want to access the static website URL within a private network, you can enable a Private Endpoint in the Storage Account and disable public access in the firewall.
Reference: Use private endpoints for Azure Storage
I hope this helps to resolve your issue.
Please donβt forget to close the thread by clicking "Accept the answer" wherever the information provided helps you, as this can be beneficial to other community members.