ASP.net 6 WebApp work correctly in Http but don't load images,css and js in https

36 Views Asked by At

I have a aspnet WebApi that is working in production using http.

I edited it to use Microsoft Azure AD authentication. The problem is that Azure Ad WebApp configuration, for production environment need an https:// redirect after login. So I configured Kestrel to use https, ask to have a valid certificate from local authority inside company LAN and configure AzureAD WebApp certificates ecc...

It start, redirect to Microsoft login, and finally return to /Account/Login successifully. The problem is that browser receive 404 error for all images, js and css that are inside wwwroot.

Using http all files are loaded, using https images,js,css don't load. So the WebApp don't work as expected.

Here the propgram code:

using GTS_Global_Technical_Standards.Models;
using GTS_Global_Technical_Standards.Models.Inferfaces;
using GTS_Global_Technical_Standards.Models.ServiziInfrastruttura;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.Identity.Web;
using Microsoft.Identity.Web.UI;
using System.Configuration;
using System.Net;
using System.Runtime.InteropServices;
using Microsoft.AspNetCore.Authentication.Negotiate;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Authentication.AzureAD.UI;
using System.Security.Claims;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.Identity.Web;
using Microsoft.Identity.Web.UI;
using DocumentFormat.OpenXml.InkML;
using DocumentFormat.OpenXml.Office2016.Drawing.ChartDrawing;
using Microsoft.Graph;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Authentication.Certificate;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.AspNetCore.Server.Kestrel.Https;
using System.Security.Cryptography.X509Certificates;

WebApplicationBuilder builder = WebApplication.CreateBuilder(args);

var initialScopes = builder.Configuration["DownstreamApi:Scopes"]?.Split(' ') ?? builder.Configuration["MicrosoftGraph:Scopes"]?.Split(' ');

builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"))
        .EnableTokenAcquisitionToCallDownstreamApi(initialScopes)
            .AddInMemoryTokenCaches();


builder.Services.Configure<OpenIdConnectOptions>(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
    options.Events = new OpenIdConnectEvents
    {
        OnTokenValidated = ctx =>
        {
            try
            {
                GTS_Global_Technical_Standards.Models.SQLserviceDB _serviceDB = new GTS_Global_Technical_Standards.Models.SQLserviceDB(builder.Configuration);

                GTSServices _GTSServices = new GTSServices(_serviceDB,null);
                // Check if user email exist in local database
                var user = _GTSServices.getUserData(ctx.Principal.Identity.Name);

                // If the user is authenticated, store its claims to cookie
                if (user != null)
                {
                    var userClaims = new List<Claim>
                        {
                            new Claim(ClaimTypes.Name, ctx.Principal.GetDisplayName()),
                            new Claim(ClaimTypes.Email, user.f_username)
                        };

                    var claimsIdentity = new ClaimsIdentity(userClaims, user.f_username);
                    if (user != null)
                    {
                        switch (user.f_level)
                        {
                            case 10:
                                claimsIdentity.AddClaim(new Claim("superAdmin", "true"));
                                break;

                            case 5:
                                claimsIdentity.AddClaim(new Claim("specialUser", "true"));
                                break;
                        }

                        claimsIdentity.AddClaim(new Claim("f_datetime_join", user.f_datetime_join.ToString("yyyy-MM-dd HH:mm:ss")));
                        claimsIdentity.AddClaim(new Claim("userid", user.user_id.ToString()));
                    }
                    else
                    {
                        // user not found must block access
                        ctx.Fail("Unauthorized");
                    }

                    ctx.Principal.AddIdentity(claimsIdentity);

                } else
                {
                    ctx.Fail("Unauthorized");
                }

            }
            catch (Exception ex)
            {
                ctx.Fail("Unauthorized");
                
            }
            return Task.CompletedTask;
        },
    };
});

builder.Services.AddControllersWithViews(options =>
{
    var policy = new AuthorizationPolicyBuilder()
        .RequireAuthenticatedUser()
        .Build();
    options.Filters.Add(new AuthorizeFilter(policy));
}).AddMicrosoftIdentityUI();

builder.Services.AddDistributedMemoryCache();

builder.Services.AddSession(options =>
{
    options.IdleTimeout = TimeSpan.FromSeconds(10);
    options.Cookie.HttpOnly = true;
    options.Cookie.IsEssential = true;

});

builder.Services.AddAuthorization(options =>
{
    
    options.AddPolicy("superAdmin", policy =>
                      policy.RequireClaim("superAdmin", "true")
                            .AddAuthenticationSchemes(CookieAuthenticationDefaults.AuthenticationScheme)
                          );
    options.AddPolicy("specialUser", policy =>
                      policy.RequireClaim("specialUser", "true")
                            .AddAuthenticationSchemes(CookieAuthenticationDefaults.AuthenticationScheme)
                          );
    
    options.AddPolicy("atLeastSpecialUser", policy =>
            policy.RequireAssertion(context => context.User.HasClaim(c =>
            (c.Type == "specialUser" || c.Type == "superAdmin"))));
});

builder.Services.AddTransient<IServiceDB, SQLserviceDB>();
builder.Services.AddTransient<GTSServices, GTSServices>();

builder.Services.AddHttpContextAccessor();

builder.Services.AddRazorPages().AddMicrosoftIdentityUI();
builder.Services.AddHttpsRedirection(options =>
{
    options.RedirectStatusCode = (int)HttpStatusCode.TemporaryRedirect;
    options.HttpsPort = 5002;
});

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}

app.UseDefaultFiles();
app.UseStaticFiles();
app.UseHttpsRedirection();

app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();
app.UseSession();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Dashboard}/{id?}");

app.MapRazorPages();
app.MapControllers();

app.Run();

and the appsettings.json relevant config: (private data changed)

"Kestrel": {
    "Endpoints": { 
      
      "HttpsInlineCertFile": {
        "Url": "https://servername.domain.local:5002",
        "ClientCertificateMode": "AllowCertificate",
        "Certificate": {
          "Path": "path_to/certificate.pfx",
          "Password": "password"
        }
      },
    }
  },
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "Domain": "domain.local",
    "TenantId": "FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF",
    "ClientId": "FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF",
    "ClientSecret": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
    "CallbackPath": "/Account/Login",
    "SkipUnrecognizedRequests": false
  },

This is the log during browser loading of resources: enter image description here

Somebody can help to understand how to resolve this issue? Thanks in advance.

1

There are 1 best solutions below

0
Mago Maverick On

Ok, I realized now, after 2 days passed to try to let work AzureAd Authentication that wwwroot content is not passed in Release folder when compiling.

So that folder was empty and all resources were missing. ‍♂️‍♂️‍♂️