Cod*_*Lee 11 c# authentication mongodb asp.net-core blazor
我有一个 Blazor 服务器应用程序,它使用 MongoDB 作为数据库,所以我试图用它来实现身份验证。所以我可以<Authenticted>, <AuthorizeView Roles="admin">在剃刀页面中使用和其他类似的标签。
内置的身份验证模板使用 SQL Server,在这种情况下我不想要,并且没有一个明确的示例说明如何自己使用另一个数据库来完成。鉴于微软在此处提供的示例
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));
}
}
}
Run Code Online (Sandbox Code Playgroud)
应该如何在应用程序中使用它?您显然不会将单个值和值类型硬编码为唯一的身份验证来源。那么应该如何参数化呢?具有本地属性,例如:
Username { get; set; }
UserType { get; set; }
Run Code Online (Sandbox Code Playgroud)
在这种情况下,你会在哪里设置?
另外,您将如何使用它来验证用户?我在ConfigurationServices(...)方法下的启动文件中添加了类:
...
services.AddScoped<AuthenticationStateProvider, MongoAuthenticationStateProvider>();
...
Run Code Online (Sandbox Code Playgroud)
我不知道如何验证任何人。我想你会以多种方式验证用户名和密码,然后当你知道它很好时,你继续更新 .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("/");
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是,返回中的导航不起作用(他们没有解释他们的代码甚至是如何编译的)并且 SignInAsync() 方法在他们显示的方式中不可用。同样,我不知道他们的代码是如何编译的。那么人们通常会如何做到这一点呢?
我找不到任何教程,范例等比其他数百个例子,仅仅使用内置的SQL服务器模板。在哪里可以找到有关如何使用它的详细信息?除了“使用内置模板”或此处的文档链接之外的任何内容都将不胜感激,因为它们都没有解释如何执行此操作。
itm*_*nus 16
内置的身份验证模板使用SQL Server,在这种情况下我不想要,并且没有一个明确的例子说明如何使用另一个数据库自己做
我猜你正在使用 ASP.NET Core Identity,对吧?如果您正在寻找使用其他提供程序的方式,请参阅官方文档
应该如何在应用程序中使用它?您显然不会将单个值和值类型硬编码为唯一的身份验证来源。那么应该如何参数化呢?
由于您使用的是 Blazor 服务器(而不是 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);
}
}
Run Code Online (Sandbox Code Playgroud)
如上所示,GetAuthenticationStateAsync()将返回由 设置的身份验证状态IHostEnvironmentAuthenticationStateProvider。所以你需要的是注入一个IHostEnvironmentAuthenticationStateProvider并调用IHostEnvironmentAuthenticationStateProvider::SetAuthenticationState(...). 最后,身份验证状态将<Authorize/>自动发送到 Blazor 。
其实,以上ServerAuthenticationStateProvider都不知道本金是否仍然有效。因此,有另一种内置的具体类为您提供:RevalidatingServerAuthenticationStateProvider。
以上代码适用于所有身份验证方案,包括 ASP.NET Core Identity、JwtBearer、AAD 等。您使用的身份验证方案或使用的数据库无关紧要。只是扩展RevalidatingServerAuthenticationStateProvider类。
例如,如果您使用的是ASP.NET核心身份(您可能会看到相关的Cookie的问题(见本线),它会产生一类的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
Run Code Online (Sandbox Code Playgroud)
由于ASP.NET Core Identity不限于 SQL Server,因此RevalidatingIdentityAuthenticationStateProvider适用于其他数据库。如果您想使用 MongoDB,请随意创建自定义MyMongoDbRevalidatingAuthenticationStateProvider.
此外,您将如何使用它来验证用户
只需像这样声明组件:
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
Run Code Online (Sandbox Code Playgroud)
你会不这样做手工,如果你使用的是默认RevalidatingServerAuthenticationStateProvider。使用 Blazor 服务器端,身份验证由 完成AuthenticationMiddleware,然后身份验证状态将<AuthorizeView/>自动传递给。并且当认证状态过期时,<AuthorizeView/>也会自动更新。
返回中的导航不起作用
实际上,您的代码应该在导航之前失败:
HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity));
Run Code Online (Sandbox Code Playgroud)
请注意 SignIn() 方法将尝试通过 HTTP 发送 cookie。但是,大多数情况下,建立连接后没有 HTTP。其实几个月前我已经回答了一个完全相同的问题。
简而言之:
RevalidatingServerAuthenticationStateProvider类似的方案RevalidatingIdentityAuthenticationStateProvider。RevalidatingIdentityAuthenticationStateProvider为您生成一个。