【问题标题】:Deployed WebAssembly Blazor application doesn't route authentication properly, but locally working部署的 WebAssembly Blazor 应用程序无法正确路由身份验证,但在本地工作
【发布时间】:2020-12-28 07:23:52
【问题描述】:

我创建了一个“普通”的 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=...

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

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

'.../身份验证/登录'

片刻之后,去

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

这是一个不存在的页面。

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

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

提前谢谢你。

【问题讨论】:

    标签: asp.net-core identityserver4 blazor-webassembly


    【解决方案1】:

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

    判断 IdentityServer 是否启动并运行的一种方法是访问此 URL https://yourdomain.com/.well-known/openid-configuration

    这个 URL 应该总是成功的。

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

    以下链接:

    【讨论】:

    • 我知道我必须学习,你是对的......我认为可能有一些开箱即用的解决方案,至少对于简单的情况......非常感谢! :-)
    猜你喜欢
    • 2023-03-19
    • 1970-01-01
    • 2020-11-02
    • 1970-01-01
    • 2020-09-16
    • 1970-01-01
    • 2021-05-29
    • 2014-10-05
    • 1970-01-01
    相关资源
    最近更新 更多