ASP.net 6 WebApp 在 Http 中正常工作,但不在 https 中加载图像、css 和 js

问题描述 投票:0回答:1

我有一个 aspnet WebApi,它正在使用 http 进行生产。

我对其进行了编辑以使用 Microsoft Azure AD 身份验证。 问题是生产环境的 Azure Ad WebApp 配置需要在登录后进行 https:// 重定向。 因此,我将 Kestrel 配置为使用 https,要求获得公司 LAN 内本地机构颁发的有效证书,并配置 AzureAD WebApp 证书 ecc...

启动,重定向到微软登录,最后成功返回到/Account/Login。 问题是浏览器收到 wwwroot 内的所有图像、js 和 css 的 404 错误。

使用 http 会加载所有文件,使用 https 则不会加载图像、js、css。因此 WebApp 无法按预期工作。

这里是程序代码:

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();

以及appsettings.json相关配置:(私有数据已更改)

"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
  },

这是浏览器加载资源时的日志:

有人可以帮助了解如何解决这个问题吗? 预先感谢。

c# asp.net-mvc https azure-active-directory kestrel
1个回答
0
投票

好吧,我现在意识到,在尝试让 AzureAd 身份验证工作 2 天后,编译时 wwwroot 内容不会传递到 Release 文件夹中。

所以该文件夹是空的,所有资源都丢失了。 🤦u200d♂️🤦u200d♂️🤦u200d♂️

© www.soinside.com 2019 - 2024. All rights reserved.