已部署的 WebAssembly Blazor 应用程序未正确路由身份验证,但在本地工作

Deployed WebAssembly Blazor application doesn't route authentication properly, but locally working

我创建了一个 'normal' WebAssembly Blazor 客户端和服务器应用程序。

我后来决定添加身份验证,所以我按照这个地址的步骤操作:

https://docs.microsoft.com/en-us/aspnet/core/blazor/security/webassembly/hosted-with-identity-server?view=aspnetcore-3.1&tabs=visual-studio

在 Blazor WebAssembly 应用程序的服务器部分以此启动代码结束:

public class Startup
{
    private readonly IWebHostEnvironment _environment;
    private readonly IConfiguration _configuration;

    public Startup(IWebHostEnvironment environment, IConfiguration configuration)
    {
        _environment = environment;
        _configuration = configuration;
    }

    public void ConfigureServices(IServiceCollection services)
    {
        if (_environment.IsDevelopment())
        {
            services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(
                    _configuration.GetConnectionString("LocalEnvironment")));
        }
        else
        {
            services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(
                    _configuration.GetConnectionString("CloudEnvironment")));
        }

        services.AddDefaultIdentity<ApplicationUser>()
            .AddRoles<ApplicationRole>()
            .AddEntityFrameworkStores<ApplicationDbContext>();

        services.AddIdentityServer()
            .AddApiAuthorization<ApplicationUser, ApplicationDbContext>(options =>
            {
                options.IdentityResources["openid"].UserClaims.Add("name");
                options.ApiResources.Single().UserClaims.Add("name");
                options.IdentityResources["openid"].UserClaims.Add("role");
                options.ApiResources.Single().UserClaims.Add("role");
            });

        JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("role");

        services.AddAuthentication()
            .AddIdentityServerJwt();

        services.AddControllersWithViews();
        services.AddRazorPages();

        services.Configure<IdentityOptions>(options =>
        {
            options.ClaimsIdentity.UserIdClaimType = ClaimTypes.NameIdentifier;

            options.User.RequireUniqueEmail = true;

            options.Password.RequiredLength = 8;
            options.Password.RequireNonAlphanumeric = true;
            options.Password.RequireLowercase = false;
            options.Password.RequireUppercase = true;
            options.Password.RequireDigit = true;
        });

        services.AddTransient<IPasswordValidator<ApplicationUser>, CustomPasswordPolicy>();
        services.AddTransient<IUserValidator<ApplicationUser>, CustomUsernameEmailPolicy>();

        services.AddTransient<IProfileService, ProfileService>();

        services.AddHttpContextAccessor();

        services.AddHsts(options =>
        {
            options.Preload = true;
            options.IncludeSubDomains = true;
            options.MaxAge = TimeSpan.FromDays(60);
        });
    }

    public void Configure(IApplicationBuilder app, ApplicationDbContext db,
        UserManager<ApplicationUser> userManager, RoleManager<ApplicationRole> roleManager)
    {
        if (_environment.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseDatabaseErrorPage();
            app.UseWebAssemblyDebugging();
        }
        else
        {
            app.UseExceptionHandler("/Error");
            app.UseHsts();
        }

        db.Database.EnsureCreated();

        app.UseHttpsRedirection();
        app.UseBlazorFrameworkFiles();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseIdentityServer();
        app.UseAuthentication();
        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapRazorPages();
            endpoints.MapControllers();
            endpoints.MapFallbackToFile("index.html");
        });

        IdentityDataInitializer.SeedTestData(userManager, roleManager);
    }
}

生成的应用程序在开发环境中(在 Kestrel 和 IIS Express 中,但当我将它部署到 Azure 服务应用程序时,身份验证部分,只有那个,不能正常工作。

例如:如果我点击主页中的登录按钮,当我在本地时会跳转到该页面:

https://localhost:5001/Identity/Account/Login?ReturnUrl=...

这是正确的路径,因为,此外,在登录后,我被正确重定向到主页。

但是当我在部署的应用程序上单击同一个按钮时,我看到地址变成了第一个

'.../authentication/login'

片刻之后,前往

'.../connect/authorize?client_id=Test1.Client&redirect_uri=...'

那是一个不存在的页面。

就我个人而言,目前我什至不明白这是服务器还是客户端问题,或者只是 Azure 上服务应用程序的配置问题...

请随时询问其他代码或任何可以提供帮助的内容。

提前谢谢你。

/connect/authorize 是 IdentityServer 侦听的端点之一,它是 application/client 应该重定向到的第一个 URL用户即将进行身份验证。

判断 IdentityServer 是否已启动且 运行 的一种方法是转到此 URL https://yourdomain.com/.well-known/openid-configuration

这个 URL 应该总是成功的。

当您部署到云和 Azure 服务应用程序时,一件事是确保您了解 HTTPS 终止的位置,它是在您的应用程序中还是在 Azure 服务中?如果它没有在应用程序 it-self 中终止,那么可能 public URL 是 HTTPS,但您的应用程序看到的是 HTTP。

要遵循的一些链接: