0

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

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

我做了什么

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. Controller 从 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. 启动.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");
        });
    }

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

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

在此处输入图像描述

4

1 回答 1

0

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

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

于 2021-03-18T21:20:37.373 回答