gpt4 book ai didi

c# - 如何使用 Blazor Server 对用户进行身份验证

转载 作者:行者123 更新时间:2023-12-03 15:31:35 25 4
gpt4 key购买 nike

我有一个使用 MongoDB 作为数据库的 Blazor Server 应用程序,所以我试图用它来实现身份验证。所以我可以使用 <Authenticted>, <AuthorizeView Roles="admin">以及 Razor 页面中的其他类似标签。

内置的身份验证模板使用 SQL Server,在这种情况下我不想要它,并且没有一个明确的示例说明如何自己使用另一个数据库进行操作。鉴于 Microsoft 提供的示例 here

using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.Authorization;

namespace BlazorSample.Services
{
public class CustomAuthStateProvider : AuthenticationStateProvider
{
public override Task<AuthenticationState> GetAuthenticationStateAsync()
{
var identity = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.Name, "mrfibuli"),
}, "Fake authentication type");

var user = new ClaimsPrincipal(identity);

return Task.FromResult(new AuthenticationState(user));
}
}
}

应该如何在应用程序中使用它?您显然不会将单个值和值类型硬编码为唯一的身份验证来源。那么应该如何参数化呢?具有本地属性,例如:
Username { get; set; }
UserType { get; set; }

在这种情况下你会在哪里设置?

另外,您将如何使用它来验证用户身份?我在 ConfigurationServices(...) 下的启动文件中添加了类方法:
...
services.AddScoped<AuthenticationStateProvider, MongoAuthenticationStateProvider>();
...

我不知道如何验证任何人。我想您可以通过多种方式验证用户名和密码,然后当您知道这很好时,您可以继续更新 .NET 中的身份验证。我正在关注一个教程,他们在后面的代码中提出了类似的建议:
using System;
using System.Linq;
using DocsPlatform.Services;
using System.Threading.Tasks;
using System.Security.Claims;
using Microsoft.AspNetCore.Http;
using System.Collections.Generic;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Components.Authorization;

namespace DocsPlatform.Pages
{
public class LoginBase : ComponentBase
{
[CascadingParameter]
private Task<AuthenticationState> authStateTask { get; set; }
protected string username { get; set; }
protected string password { get; set; }

protected async Task LoginUser()
{
bool isValid = true;

isValid = dbService.ValidateUser(username, password);

string email = dbService.GetEmail(username);

var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, username),
new Claim(ClaimTypes.Email, email),
};

var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity));

return NavigationManager.NavigateTo("/");
}
}
}


但是,返回中的导航不起作用(他们甚至没有解释他们的代码是如何编译的),并且 SignInAsync() 方法在他们展示的方式中不可用。同样,我不知道他们的代码是如何编译的。那么通常如何做到这一点呢?

除了数百个仅使用内置 SQL Server 模板的示例之外,我找不到任何教程、示例等。在哪里可以找到有关如何使用它的详细信息?除了“使用内置模板”或文档链接 here 之外的任何内容将不胜感激,因为两者都没有解释如何做到这一点。

最佳答案

The built-in authentication template uses SQL Server, which I don't want in this case, and there isn't a clear example of how to do it yourself with another database



我猜你正在使用 ASP.NET Core 身份 , 对?如果您正在寻找使用其他提供程序的方法,请参阅 official docs

How should one use this in an application? You obviously wouldn't hard code a single value, and value-type, as your only source of authenticating. So how should that be parameterized?



由于您使用的是 Blazor Server(而不是 Blazor Wasm),因此您不必自定义 GetAuthenticationStateAsync()方法,然后手动创建主体。已经有一个内置的 ServerAuthenticationStateProvider 两者都继承自 AuthenticationStateProvider并实现 IHostEnvironmentAuthenticationStateProvider界面:

// source code of the built-in ServerAuthenticationStateProvider 
public class ServerAuthenticationStateProvider : AuthenticationStateProvider, IHostEnvironmentAuthenticationStateProvider
{
private Task<AuthenticationState> _authenticationStateTask;

/// <inheritdoc />
public override Task<AuthenticationState> GetAuthenticationStateAsync()
=> _authenticationStateTask
?? throw new InvalidOperationException($"{nameof(GetAuthenticationStateAsync)} was called before {nameof(SetAuthenticationState)}.");

/// <inheritdoc />
public void SetAuthenticationState(Task<AuthenticationState> authenticationStateTask)
{
_authenticationStateTask = authenticationStateTask ?? throw new ArgumentNullException(nameof(authenticationStateTask));
NotifyAuthenticationStateChanged(_authenticationStateTask);
}
}

如您在上面看到的, GetAuthenticationStateAsync()将返回 IHostEnvironmentAuthenticationStateProvider 设置的身份验证状态.所以你需要注入(inject)一个 IHostEnvironmentAuthenticationStateProvider并调用 IHostEnvironmentAuthenticationStateProvider::SetAuthenticationState(...) .最后,身份验证状态将发送到 Blazor <Authorize/>自动地。

其实上面的 ServerAuthenticationStateProvider不知道校长是否仍然有效。所以还有另一个内置的具体类: RevalidatingServerAuthenticationStateProvider .

上面的代码适用于每种身份验证方案,包括 ASP.NET Core Identity、JwtBearer、AAD 等。您使用什么身份验证方案或使用哪个数据库都没有关系。只需扩展 RevalidatingServerAuthenticationStateProvider类(class)。

例如,如果您使用的是 ASP.NET Core 身份 (您可能会看到与 Cookies 相关的问题(参见 this thread ),它将生成一个 RevalidatingIdentityAuthenticationStateProvider 类,它使用 UserManager<TUser> 来验证主体是否有效。
public class RevalidatingIdentityAuthenticationStateProvider<TUser>
: RevalidatingServerAuthenticationStateProvider where TUser : class
{
...

protected override async Task<bool> ValidateAuthenticationStateAsync(
AuthenticationState authenticationState, CancellationToken cancellationToken)
{
// Get the user manager from a new scope to ensure it fetches fresh data
// use the UserManager to determine whether the current principal is still valid

由于 ASP.NET Core 标识不限于 SQL Server, RevalidatingIdentityAuthenticationStateProvider适用于其他数据库。如果您想使用 MongoDB,请随意创建自定义 MyMongoDbRevalidatingAuthenticationStateProvider .

Also how would you then use this to authenticate a user



只需像这样声明组件:

<AuthorizeView>
<Authorized>
...
</Authorized>
<NotAuthorized>
...
</NotAuthorized>
</AuthorizeView>

你会 不是 去做 手动 如果您使用默认 RevalidatingServerAuthenticationStateProvider .对于 Blazor 服务器端,身份验证由 AuthenticationMiddleware 完成。 ,然后是 身份验证状态将传递给 <AuthorizeView/>自动 .并且当身份验证状态到期时, <AuthorizeView/>也会自动更新。

the navigation in the return doesn't work



实际上,您的代码在导航之前应该会失败:
HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity));

请注意,SignIn() 方法将尝试通过 HTTP 发送 cookie。但是,大多数情况下,连接建立后没有 HTTP。其实我有 answered an exactly same question several month ago .

简而言之:
  • 无论您使用哪种身份验证方案,实现 RevalidatingServerAuthenticationStateProvider喜欢 RevalidatingIdentityAuthenticationStateProvider如果你需要。
  • 如果您使用的是 ASP.NET Core Identity,则会生成一个 RevalidatingIdentityAuthenticationStateProvider为你。
  • 如果您想使用 ASP.NET Core Identity + MongoDB,请关注 official docs来实现这样的功能。
  • 如果要使用 ASP.NET Core Identity + Blazor Server Side,并使用 SignIn(...) 发送 cookie,请不要直接执行此操作。见 this thread更多细节。
  • 关于c# - 如何使用 Blazor Server 对用户进行身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60383601/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com