نحوهی پیاده سازی AuthenticationStateProvider در پروژههای Blazor Server 8x
در کدهای زیر، ساختار کلی کلاس AuthenticationStateProvider ارائه شدهی توسط قالب رسمی پروژههای Blazor Server به همراه مباحث اعتبارسنجی مبتنی بر ASP.NET Core Identity را مشاهده میکنید:
public class IdentityRevalidatingAuthenticationStateProvider : RevalidatingServerAuthenticationStateProvider { protected override TimeSpan RevalidationInterval => TimeSpan.FromMinutes(30); protected override async Task<bool> ValidateAuthenticationStateAsync( AuthenticationState authenticationState, CancellationToken cancellationToken) { // ... } }
برای مثال در اینجا (یعنی کلاس بازنویسی کنندهی متد ValidateAuthenticationStateAsync که توسط تایمر کلاس پایه فراخوانی میشود) اعتبار security stamp کاربر جاری، هر نیم ساعت یکبار بررسی میشود. اگر فاقد اعتبار بود، کلاس پایهی استفاده شده، سبب LogOut خودکار این کاربر میشود.
نحوهی پیاده سازی AuthenticationStateProvider در پروژههای Blazor WASM 8x
دو نوع پروژهی مبتنی بر وباسمبلی را میتوان در دات نت 8 ایجاد کرد: پروژههای حالت رندر Auto و پروژههای حالت رندر WASM
در هر دوی اینها، از کامپوننت ویژهای به نام PersistentComponentState استفاده شدهاست که معرفی آنرا در قسمت هشتم این سری مشاهده کردید. کار این کامپوننت در سمت سرور به صورت زیر است:
public class PersistingRevalidatingAuthenticationStateProvider : RevalidatingServerAuthenticationStateProvider { public PersistingRevalidatingAuthenticationStateProvider( ILoggerFactory loggerFactory, IServiceScopeFactory scopeFactory, PersistentComponentState state, IOptions<IdentityOptions> options) : base(loggerFactory) { // ... } protected override TimeSpan RevalidationInterval => TimeSpan.FromMinutes(30); protected override async Task<bool> ValidateAuthenticationStateAsync( AuthenticationState authenticationState, CancellationToken cancellationToken) { // ... } private async Task OnPersistingAsync() { // ... _state.PersistAsJson(nameof(UserInfo), new UserInfo { UserId = userId, Email = email, }); // ... } }
public class PersistentAuthenticationStateProvider(PersistentComponentState persistentState) : AuthenticationStateProvider { private static readonly Task<AuthenticationState> _unauthenticatedTask = Task.FromResult(new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity()))); public override Task<AuthenticationState> GetAuthenticationStateAsync() { if (!persistentState.TryTakeFromJson<UserInfo>(nameof(UserInfo), out var userInfo) || userInfo is null) { return _unauthenticatedTask; } Claim[] claims = [ new Claim(ClaimTypes.NameIdentifier, userInfo.UserId), new Claim(ClaimTypes.Name, userInfo.Email), new Claim(ClaimTypes.Email, userInfo.Email) ]; return Task.FromResult( new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity(claims, authenticationType: nameof(PersistentAuthenticationStateProvider))))); } }
بنابراین PersistentComponentState کار پرکردن اطلاعات یک کش مانند را در سمت سرور انجام داده و آنرا به صورت سریالایز شده با قالب JSON، به انتهای HTML صفحه اضافه میکند. سپس زمانیکه کلاینت بارگذاری میشود، این اطلاعات را خوانده و استفاده میکند. یکبار از متد PersistAsJson آن در سمت سرور استفاده میشود، برای ذخیره سازی اطلاعات و یکبار از متد TryTakeFromJson آن در سمت کلاینت، برای خواندن اطلاعات.
یک نکته: پیاده سازی anti-forgery-token هم با استفاده از PersistentComponentState صورت گرفتهاست.