Blazor 交互式服务器身份验证

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

使用这种交互模式,我无法以任何方式进行身份验证。我尝试的最后一件事是通过 HttpClient 发送请求。 cookie 已生成并添加到浏览器中,但我仍然未经授权。

请告诉我该怎么做。 Blazor的其他操作方式,我不感兴趣。在验证数据时,会重新加载页面,我不需要它。谢谢你。

登录.razor

<div class="row">
    <h3>Login</h3>
    <div class="section-description contact-form">
        <EditForm Model="@Model" OnValidSubmit="Authenticate">
            <label class="errorMessage" style="display:@Display">@ErrorMessage</label>
            <DataAnnotationsValidator />
            <div class="text-left">
                <ValidationMessage For="() => Model.Email" class="errorMessage" />
                <label for="Email" class="form-label">Email</label>
                <InputText @bind-Value="Model.Email" class="form-control" />
            </div>
            <div class="text-left">
                <ValidationMessage For="() => Model.Password" class="errorMessage" />
                <label for="Password" class="form-label">Password</label>
                <InputText type="Password" @bind-Value="Model.Password" class="form-control" />
            </div>
            <div class="box">
                <button class="btn button-game" type="submit">
                    <span class="button-game-bg-left"></span>
                    <span class="button-game-bg-mid">
                        <span>Enter</span>
                    </span>
                    <span class="button-game-bg-right"></span>
                </button>
            </div>
        </EditForm>
    </div>
</div>



@code {
    protected override void OnInitialized()
    {
        var httpContext = HttpContextAccessor.HttpContext;
        if (httpContext.User.Identity.IsAuthenticated)
        {
            httpContext.Response.Redirect("/lobby");
        }
    }

    [SupplyParameterFromForm]
    LoginViewModel Model { get; set; } = new();

    async Task Authenticate()
    {
        HttpClient httpClient = ClientFactory.CreateClient();
        var response = await httpClient.PostAsJsonAsync("https://localhost:7051/api/auth", Model);
        if (response.IsSuccessStatusCode)
        {
            HttpContextAccessor.HttpContext.Response.Redirect("/Lobby");
        }
        else
        {
            // Handle error response
        }
    }
}

帐户控制器

    public class AccountController : Controller
    {

        private readonly SignInManager<User> _signInManager;

        public AccountController(SignInManager<User> signInManager)
        {
            _signInManager = signInManager;
        }

        [Route("api/auth")]
        [HttpPost]
        public async Task<IActionResult> Login([FromBody] LoginViewModel model)
        {
            var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, false);
            if (result.Succeeded)
            {
                return Ok();
            }
            else
            {
                return BadRequest("Not valid password");
            }
        }
    }

什么都试过了。

去看解决方案,操作方式: @rendermode RenderMode.InteractiveServer

c# asp.net-core blazor razor-pages
1个回答
0
投票

如果您的控制器和 blazor 页面位于同一项目中(均使用 localhost:7051 ) 您可以直接访问“https://localhost:7051/api/auth”,然后

signInManager.PasswordSignInAsync
将在
浏览器cookie存储
中为下域localhost:7051生成登录cookie。该 cookie 将使域中的“httpContext.User.Identity.IsAuthenticated”成为 true。

但是您正在使用 httpclient 来调用 auth 端点。 cookie 将生成到“httpclient”。这是没有用的,cookie无处可保存。所以httpcontext找不到cookie并且永远不会被认证。

事实上,您应该实现authenticationstateprovider来保存blazor前端的身份验证状态和用户信息。只有这样,您才能在单独的项目中创建控制器和 blazor 页面。 (不在同一域中)。如果他们使用不同的域,则后端身份验证端点不应该使用signinasync(因为为后端domian生成cookie对于前端来说是无用的)。相反,此端点应该返回一个令牌。然后前端 Blazor 页面将使用 httpclient 获取此令牌来设置身份验证状态。

参考:

https://chrissainty.com/securing-your-blazor-apps-authentication-with-clientside-blazor-using-webapi-aspnet-core-identity/

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