首页 > 解决方案 > Blazor .Net Core 3.0 Preview 9 - AuthenticationStateProvider 实现问题

问题描述

在我们的 Blazor 应用程序中,我们将覆盖默认实现AuthenticationStateProvider以允许使用 out Jwt。

由于升级到Preview 9它现在需要将AthenticationResponse响应包装在 aTask中。

我有以下代码;

public class JwtAuthenticationStateProvider : AuthenticationStateProvider
{
    private bool _isUserLoggedIn = false;

    private readonly HttpClient _httpClient;
    private readonly IAuthService _authService;
    private readonly ILogger<JwtAuthenticationStateProvider> _logger;

    public JwtAuthenticationStateProvider(HttpClient httpClient, IAuthService authService, ILogger<JwtAuthenticationStateProvider> logger)
    {
        _httpClient = httpClient;
        _authService = authService;
        _logger = logger;
    }

    public override async Task<AuthenticationState> GetAuthenticationStateAsync()
    {
        if(!_isUserLoggedIn)
        {
            return await Task.FromResult(new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity())));
        }
        else
        {
            var tokenResponse = await _authService.GetCurrentAuthTokenAsync();

            if (tokenResponse.HasError)
            {
                var anonymousUser = new ClaimsPrincipal(new ClaimsIdentity());
                return await Task.FromResult(new AuthenticationState(anonymousUser));
            }

            var claimsResponse = await _authService.GetCurrentUserClaimsAsync();

            if(claimsResponse.HasError)
            {
                var anonymousUser = new ClaimsPrincipal(new ClaimsIdentity());
                return await Task.FromResult(new AuthenticationState(anonymousUser));
            }

            _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", tokenResponse.Result);
            return await Task.FromResult(new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity(claimsResponse.Result, "apiAuth"))));
        }
    }

    public async Task MarkUserAsAuthenticated()
    {
        if(!_isUserLoggedIn)
            _ = KeepSessionAsync();

        var claimsResponse = await _authService.GetCurrentUserClaimsAsync();
        var authenticatedUser = new ClaimsPrincipal(new ClaimsIdentity(claimsResponse.Result, "apiAuth"));
        NotifyAuthenticationStateChanged(await Task.FromResult(new AuthenticationState(authenticatedUser)));
    }

    public void MarkUserAsLoggedOut()
    {
        _isUserLoggedIn = false;
        _httpClient.DefaultRequestHeaders.Authorization = null;
        var anonymousUser = new ClaimsPrincipal(new ClaimsIdentity());
        NotifyAuthenticationStateChanged(Task.FromResult(new AuthenticationState(anonymousUser)));
    }
}

但是我收到以下错误GetAuthenticationStateAsync()

'JwtAuthenticationStateProvider.GetAuthenticationStateAsync()':返回类型必须是 'Task' 以匹配被覆盖的成员 'AuthenticationStateProvider.GetAuthenticationStateAsync()'

谁能解释一下这里发生了什么?

标签: c#blazor.net-core-3.0blazor-client-side

解决方案


一个异步方法返回一个任务:

如果您返回:return await Task.FromResult(new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity(claimsResponse.Result, "apiAuth"))));您将返回一个Task<Task<AuthenticationState>>

只需返回:return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity(claimsResponse.Result, "apiAuth")));

您的代码应该是:

    public override async Task<AuthenticationState> GetAuthenticationStateAsync()
    {
        if(!_isUserLoggedIn)
        {
            return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity()));
        }
        else
        {
            var tokenResponse = await _authService.GetCurrentAuthTokenAsync();

            if (tokenResponse.HasError)
            {
                var anonymousUser = new ClaimsPrincipal(new ClaimsIdentity());
                return new AuthenticationState(anonymousUser);
            }

            var claimsResponse = await _authService.GetCurrentUserClaimsAsync();

            if(claimsResponse.HasError)
            {
                var anonymousUser = new ClaimsPrincipal(new ClaimsIdentity());
                return new AuthenticationState(anonymousUser);
            }

            _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", tokenResponse.Result);
            return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity(claimsResponse.Result, "apiAuth")));
        }
    }

推荐阅读