.NET MAUI Blazor с общей библиотекой пользовательского интерфейса и аутентификацией

Я пытаюсь написать приложение .NET MAUI Blazor, которое разделяет пользовательский интерфейс с традиционным приложением Blazor, как можно увидеть в примере BlazorWeather, который можно найти по адресу https://github.com/danroth27/BlazorWeather.

Мой поворот в этой формуле заключается в том, что я хочу иметь возможность использовать аутентификацию в своем приложении и делиться как можно большим количеством кода. В идеале я бы хотел поместить всю логику приложения в общий пользовательский интерфейс (и API, который, конечно, также будет одним и для Web, и для MAUI).

Я пытался собрать свой собственный рабочий прототип, собирая шаблоны проектов Microsoft и связывая их, но мне не удалось заставить аутентификацию работать из MAUI. Я всегда получаю ошибку:

      GetAuthenticationStateAsync was called before SetAuthenticationState.
   at Microsoft.AspNetCore.Components.Server.ServerAuthenticationStateProvider.GetAuthenticationStateAsync()
   at Microsoft.AspNetCore.Components.Authorization.CascadingAuthenticationState.OnInitialized()
   at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync()

Я был бы очень рад, если бы кто-нибудь мог указать мне на рабочий шаблон, на котором я мог бы построить свое приложение. Любые отзывы приветствуются.

1 ответ

Я также столкнулся с этой проблемой.

Вот что я нашел. Я получал эту ошибку, когда мой AuthenticationState не возвращал правильный результат. Это реализация CustomAuthenticationStateProvider, реализующая AuthenticationStateProvider по умолчанию:

      public class CustomAuthenticationStateProvider :AuthenticationStateProvider
{

    public async Task Login(string token)
    {
        await SecureStorage.SetAsync("accounttoken", token);
        NotifyAuthenticationStateChanged(GetAuthenticationStateAsync());
    }

    public async Task Logout()
    {
        SecureStorage.Remove("accounttoken");
        NotifyAuthenticationStateChanged(GetAuthenticationStateAsync());
    }

    public override async Task<AuthenticationState>GetAuthenticationStateAsync()
    {

        try
        {
            var userInfo = await SecureStorage.GetAsync("accounttoken");
            if (userInfo != null)
            {
                var claims = new[] { new Claim(ClaimTypes.Name, "User") };
                var identity = new ClaimsIdentity(claims, "Server authentication");
                return new AuthenticationState(new ClaimsPrincipal(identity));
            }
        }
        catch (HttpRequestException ex)
        {
            //This should be implemented better
            Console.WriteLine("Request failed:" + ex.ToString());
        }

        return new AuthenticationState(new ClaimsPrincipal());
     }
}

Затем в моей программе MauiProgram я добавил:

      builder.Services.AddAuthorizationCore();
builder.Services.AddScoped<AuthenticationStateProvider, CustomAuthenticationStateProvider>();

Я возвращал ноль вместо

      new AuthenticationState(new ClaimsPrincipal());

Что вызывало ту же ошибку:

      GetAuthenticationStateAsync was called before SetAuthenticationState.
at Microsoft.AspNetCore.Components.Server.ServerAuthenticationStateProvider.GetAuthenticationStateAsync()
at Microsoft.AspNetCore.Components.Authorization.CascadingAuthenticationState.OnInitialized()
at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync()

Надеюсь это поможет!

Другие вопросы по тегам