【问题标题】:Blazor .Net Core 3.0 Preview 9 - AuthenticationStateProvider implementation issueBlazor .Net Core 3.0 Preview 9 - AuthenticationStateProvider 实现问题
【发布时间】:2019-09-09 08:45:35
【问题描述】:

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

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

我有以下代码;

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()'

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

【问题讨论】:

  • 也许您正在混合您引用的程序集,并且您使用的任务与基类中的任务不同,即。不同的程序集实现Task?
  • 不是我不认为我在引用 System.Threading.Tasks.Task 并且 AuthenticationStateProvider 类的元数据也是如此?
  • 如果您删除 await 并只保留 return Task.FromResult(new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity(claimsResponse.Result, "apiAuth")))); 会发生什么?
  • @HenkHolterman 不,它不是直接从 AuthenticationStateProvider 扩展而来的

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


【解决方案1】:

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

如果您返回:return await Task.FromResult(new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity(claimsResponse.Result, "apiAuth"))));,您将返回 Task&lt;Task&lt;AuthenticationState&gt;&gt;

只需返回: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")));
        }
    }

【讨论】:

  • 我已经尝试过了(因为这是在预览版 9 之前的编码方式)。但是,这会给出错误AuthenticationState does not contain a defination for GetAwaiter accepting a first argument of type AuthenticationState could not be found
  • oups,删除等待,它应该可以工作。我更新了回复
猜你喜欢
  • 2020-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-18
  • 2020-01-24
  • 2020-01-10
  • 2020-01-12
相关资源
最近更新 更多