控制器不执行代码Blazor 服务器端

问题描述

我的目标创建一个简单的登录表单,以便使用 Cookie 身份验证在我的 Blazor 服务器端应用中对用户进行身份验证和授权。

我的问题 一切正常... EditForm 将值传递给我的控制器。控制器验证用户凭据。然后运行 ​​HttpContext.SignInAsync(claims) 并返回 Ok()。 但是 Cookie 没有通过,用户也没有进行 Authenticate。

我做了什么

1. EditForm 将用户输入传递给 ValidSubmit 上的 displayLoginModel()。

    <div class="row">
    <div class="col-8">
        <EditForm Model="@userLogin" OnValidSubmit="OnValidLogin">
            <DataAnnotationsValidator />
            <ValidationSummary />
            <div class="mb-4 row">
                <p class="col-sm-4 font-weight-bold">Email</p>
                <div class="col-sm-8">
                    <InputText @bind-Value="userLogin.Email" class="form-control" />
                </div>
            </div>
            <div class="mb-4 row">
                <p class="col-sm-4 font-weight-bold">Password</p>
                <div class="col-sm-8">
                    <InputText @bind-Value="userLogin.Password" class="form-control"  />
                </div>
            </div>
                <button class="btn btn-outline-primary col-sm-4" type="submit"><strong>Login EditForm</strong></button>
        </EditForm>
    </div>
</div>

2. OnValidLogin 向表单控制器发送请求

        public displayLoginModel userLogin = new displayLoginModel();
    private async Task OnValidLogin()
    {
        var requestMessage = new HttpRequestMessage()
        {
            Method = new HttpMethod("POST"),RequestUri = new Uri("https://localhost:44370/Form"),Content = JsonContent.Create(userLogin)      
        };
        var client = httpfac.CreateClient();
        var response = await client.SendAsync(requestMessage);           
    }

3.控制器从 displayloginModel 获取用户凭据并验证 Ok()。

    [HttpPost]
    public async Task<ActionResult> Post(displayLoginModel _userLogin)
    {       
        if (_userLogin.Email == "this@Email.com")
        {     
            ClaimsIdentity claimsIdentity = new ClaimsIdentity(new List<Claim>
            {
                new Claim(ClaimTypes.Role,"ActiveUser")
            },"auth");
            ClaimsPrincipal claims = new ClaimsPrincipal(claimsIdentity);
            await HttpContext.SignInAsync(claims);         
            return Ok();
        }
        else
        {
            return BadRequest();
        }
    }

4. Startup.cs

        public void ConfigureServices(IServiceCollection services)
    {

        services.AddHttpClient();
        services.AddHttpContextAccessor(); 
        services.AddAuthentication("Cookies").AddCookie(options =>
        {
            options.SlidingExpiration = true; 
        });        
        services.AddRazorPages();
        services.AddServerSideBlazor();
    }

public void Configure(IApplicationBuilder app,IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Error");
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseRouting();

        app.UseAuthentication(); 
        app.UseAuthorization(); 
        
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
            endpoints.MapBlazorHub();
            endpoints.MapFallbackToPage("/_Host");
        });
    }

为什么控制器没有让用户登录,我错过了什么?

解决方案结构的图像如下所示:

enter image description here

解决方法

因为 Blazor 服务器使用 websockets(Blazor 电路)在控制器上呈现 UI,await HttpContext.SignInAsync(claims); 返回一个 cookie 标头,以便浏览器可以在下一个页面加载时获得授权。这意味着您实际上是在服务器端进行身份验证,而不是从客户端进行身份验证,因为您尚未重新加载页面上下文来更新 cookie。默认身份登录使用 MVC 架构进行身份验证过程是有原因的。 :)

我的建议是,切换到基于 API 的身份验证/授权或在流程中使用传统登录。