Hi @takeolexus,
I have found a workaround for this issue, and I could share with you. And I am still waiting for app service expert's reply.
Program.cs
using BlazorServerEasyAuth.Data;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Components.Server;
using Microsoft.AspNetCore.Components.Server.Circuits;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Newtonsoft.Json.Linq;
using System.Net;
using System.Security.Claims;
using System.Security.Principal;
namespace BlazorServerEasyAuth
{
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
builder.Services.AddSingleton<WeatherForecastService>();
builder.Services.AddScoped<AuthenticationStateProvider, ServerAuthenticationStateProvider>();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.Use(async (context, next) =>
{
// Create a user on current thread from provided header
if (context.Request.Headers.ContainsKey("X-MS-CLIENT-PRINCIPAL-ID"))
{
// Read headers from Azure
var azureAppServicePrincipalIdHeader = context.Request.Headers["X-MS-CLIENT-PRINCIPAL-ID"][0];
var azureAppServicePrincipalNameHeader = context.Request.Headers["X-MS-CLIENT-PRINCIPAL-NAME"][0];
#region extract claims via call /.auth/me
//invoke /.auth/me
var cookieContainer = new CookieContainer();
HttpClientHandler handler = new HttpClientHandler()
{
CookieContainer = cookieContainer
};
string uriString = $"{context.Request.Scheme}://{context.Request.Host}";
foreach (var c in context.Request.Cookies)
{
cookieContainer.Add(new Uri(uriString), new Cookie(c.Key, c.Value));
}
string jsonResult = string.Empty;
using (HttpClient client = new HttpClient(handler))
{
var res = await client.GetAsync($"{uriString}/.auth/me");
jsonResult = await res.Content.ReadAsStringAsync();
}
//parse json
var obj = JArray.Parse(jsonResult);
string user_id = obj[0]["user_id"].Value<string>(); //user_id
// Create claims id
List<Claim> claims = new List<Claim>();
foreach (var claim in obj[0]["user_claims"])
{
claims.Add(new Claim(claim["typ"].ToString(), claim["val"].ToString()));
}
// Set user in current context as claims principal
var identity = new GenericIdentity(azureAppServicePrincipalNameHeader);
identity.AddClaims(claims);
#endregion
// Set current thread user to identity
context.User = new GenericPrincipal(identity, null);
};
await next.Invoke();
});
app.UseRouting();
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");
app.Run();
}
}
}
Index.razor
@page "/"
@using System.Security.Claims;
@inject AuthenticationStateProvider AuthenticationStateProvider
<h1>Hello, @UserName!</h1>
@code {
private string? UserName;
protected override async Task OnInitializedAsync()
{
var authenticationState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
var user = authenticationState.User;
if (user.Identity.IsAuthenticated)
{
// Find the user's name claim
var userNameClaim = user.FindFirst(ClaimTypes.Name);
if (userNameClaim != null)
{
UserName = userNameClaim.Value;
}
}
}
}
If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.
Best regards,
Jason